"Пожирание" одних функций другими. как называется?

Dasar

"пожирание" одних функций другими - как правильно называется, и где что-то похожее реализовано?
"пожирание" - это преобразование вида, например:
NumberGenerate(1, inf).Where(i => i %3) преобразуется сначала в NumberGenerate(1, inf, i => i% 3) а потом NumberGenerate(3, i=>i+3)
или другими словами:
допустим, есть супер-пупер генератор чисел, причем настолько крутой, что если ему передать условие фильтрации, то он автоматически это преобразует в функции получении первого числа и последующего числа из предыдущего.
соответственно далее: если компилятор видит, что после вызова генератор идет сразу вызов фильтра, то фильтр необходимо передать самой генерирующей функции.
основной вопрос: как специфировать вот такие хитрые функции (как данный генератор чтобы компилятор понял что ему делать?
спецификация функции генератора:
вход: int start, int end
выход: IEnumerable<int>
а как правильно еще специфицировать что функция умеет еще немножечко шить "заглатывать" фильтр примененный к своему выходу?

apl13

О боже мой! Ты действительно хорошо представляешь себе современные технологии программирования! :pray:

Dasar

хочешь сказать, что это использует каждый второй язык, а я всё пропустил. или что?

okis

Это замечательный подход, к исследованию которого приложили руку и российские учёные, например, В. Турчин.

Не называю сразу, чтобы не быть капитаном в свете предыдущего поста.

Dasar

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

okis

Какой-то очень общий вопрос. Могут быть оптимизации на уровне компилятора или ВМ, которые это выделят, может быть возможность обработки и преобразования дерева программы на уровне языка (такое, как я слышал, довольно просто делается в лиспе, через какую-нибудь рефлексию, наверное, можно и в шарпе). Как именно называется такая оптимизация, как в заглавном посте, я не знаю.

schipuchka1

numXGenerate = [x % 3 | x : numGenerate]

Dasar

у меня больше вопрос: как это специфицировать? причем не какими именно закорючками, а какой смысл(?) вот у такой хитрой функции и преобразования.
пока у меня ход мыслей следующий:
спецификация фильтра: T* -> T* with Condition, где Condition это условие на элемент или на последовательность
Generator тогда получается имеет базовый выход: T*
плюс со своего хвоста он готов "хавать" функции вида T* -> T* with Condition.
вот тут вопрос, можно ли не вводить понятие "хавает с хвоста"? а определить его через какие-то более базовые(какие?)?
можно по идее вот так:
Generator берет range, а выдает T*, но может выдать сразу(более оптимальным образом по тому или иному критерию) T* with Condition, если ему дадут этот самый Condition
спецификация на весь кусок (генератор + фильтр) получается [range] -> T* with Condition и необходимо лишь подобрать самую оптимальную функцию, которая умеет это делать. а это может быть сам генератор с переданным ему Condition или вообще внешний метод
зы
что-то у меня уложилось, спасибо.
 

okis

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

Dasar

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

okis

можно посмотреть в сторону [типизированного] лямбда-исчисления.

Dasar

если продолжить предыдущую мысль, то можно считать что у выделенного выражения:
range.generate.where(condition) тип результа и есть T<range.generate.where(condition)>
и есть функции generate со спецификациями:
range generate T<range.generate>
range generate T<range.generate.where(condition)>
а дальше остается лишь задача перебора всех пар входов и выходов в дереве программы, и подбора оптимального набора конструкций которые выдают тот же результат

Dasar

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

okis

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

Maurog

"пожирание" одних функций другими - как правильно называется, и где что-то похожее реализовано?
например, инлайнинг - частный случай подобной оптимизации
основной вопрос: как специфировать вот такие хитрые функции (как данный генератор чтобы компилятор понял что ему делать?
с помощью декларации типов
смотрим в сторону хаскела: ранк-2, ранк-N полиморфизмы, вывод типа
зы: я не в теме, просто в лужу :(

Dasar

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