Що таке поетапні функції (концептуально)?


24

В останній статті CACM [1] автори представляють реалізацію для поетапних функцій . Вони використовують термін так, ніби він був добре відомий, і жодна з посилань не виглядає очевидним вступом.

Вони дають коротке пояснення (зміна мого та посилального номера змінено; в оригіналі - 22)

У контексті генерування програм багатоступеневе програмування (MSP, постановка на короткий час), встановлене Taha та Sheard [2], дозволяє програмістам явно затримати оцінку програмного виразу на більш пізній стадії (таким чином, постановка виразу). Нинішній етап ефективно діє як генератор коду, який складає (і, можливо, виконує) програму наступного етапу.

Однак Таха і Шерд пишуть (моє наголос):

Багатоетапна програма - це така, яка передбачає генерацію, компіляцію та виконання коду, все це в межах одного процесу. Багатоетапні мови експресують багатоетапні програми. Постановочне і, отже, багатоступеневе програмування вирішують потребу в рішеннях загального призначення, які не платять загальні витрати інтерпретації часу.

Вони продовжують описувати старі роботи, які нібито показують, що інсценізація ефективна, що говорить про те, що концепція є ще старшою. Вони не дають посилання на сам термін.

Ці твердження здаються ортогональними, якщо не суперечливими; можливо, те, що пишуть Ромпф і Одерський, є додатком того, що пропонують Таха і Шеард, але, можливо, це інша точка зору на те саме. Вони, схоже, погоджуються, що важливим моментом є те, що програми (пере) записують частини себе під час виконання, але я не знаю, чи це необхідна та / або достатня здатність.

Отже, що таке інсценізація відповідно - це інтерпретація інсценізації в цьому контексті? Звідки походить цей термін?


  1. Легка модульна постановка: прагматичний підхід до створення коду виконання та складених DSL від T. Rompf та M. Odersky (2012)
  2. MetaML та багатоетапне програмування з явними анотаціями У. Таха та Т. Шеарда (2000)

Яке протиріччя ви бачите між двома твердженнями? Для мене вони схожі на те, що вони говорять про одне і те ж, з різним наголосом.
Жил 'ТАК - перестань бути злим'

@Gilles Мені не потрібно генерація / -компіляція коду виконання, щоб затримати оцінку чогось (див. Суцільність). Це може бути так, що це просто інший акцент (я визнаю, що варіант у питанні), але я не можу сказати.
Рафаель

Ви можете ознайомитись із документацією щодо впровадження мови та метапрограмування програми Julia на @generated functions: julia.readthedocs.org/en/latest/manual/metaprogramming/…
SalchiPapa

Відповіді:


21

Наскільки мені відомо, термін поетапні обчислення вперше використав Білл Шерліс у цій роботі . До цього термін « часткове оцінювання » використовувався майже для однієї і тієї ж концепції, але ідея поетапних обчислень тонко відрізняється. Обидві ідеї пов'язані з теоремою Smn Клейна .

Якщо у вас є функція з двох аргументів, але ви знаєте один аргумент, скажімо, , ви можете виконати частину обчислення функції відразу, використовуючи знання першого аргументу. Тоді вам залишається функція , обчислення якої залежать лише від другого, невідомого аргументу.m ϕ m ( n )ϕ(m,n)mϕm(n)

Ідея часткової оцінки полягає в обчисленні спеціалізованої функції автоматично . Враховуючи код для вихідної функції , часткове оцінювання робить статичний аналіз, щоб визначити, які біти коду залежать від а які біти залежать від , і перетворює його у функцію яка, з , будує . Другий аргумент може бути поданий до цієї спеціалізованої функції.ϕ m n ϕ m ϕ m nϕm(n) ϕmnϕmϕmn

Ідея поетапних обчислень - спочатку подумати про функцію . Його називають "поетапною" функцією, оскільки вона працює в декілька етапів. Після того, як ми дамо йому перший аргумент , він побудує код спеціалізованої функції . Це "перший етап". На другому етапі другий аргумент подається до що виконує решту роботи. m ϕ m ϕ mϕmϕmϕm

Отже, завдання часткового оцінювання полягає в перетворенні коду для звичайної функції в поетапну функцію . Шерліс передбачав, що цю трансформацію можна здійснити за загальнішими механізмами, ніж попередні методи часткової оцінки. Тема "поетапних обчислень" зараз стосується таких питань, як:ϕ ϕϕ

  • Як визначити поетапні функції?
  • Які мови програмування та системи типів слід використовувати для визначення поетапних функцій?
  • Яка семантика таких мов?
  • Як ми можемо забезпечити узгодженість та правильність поетапних функцій?
  • Які методи корисні для автоматичного або напівавтоматичного побудови поетапних функцій?
  • Як ми доводимо правильність таких прийомів?

Поетапне обчислення може бути дуже важливим на практиці. Насправді кожен компілятор фактично проводить поетапні обчислення. Враховуючи вихідну програму, вона будує перекладену та оптимізовану цільову програму, яка може потім взяти фактичний вклад та обчислити результат. Важко писати поетапні програми обчислень на практиці, оскільки нам доведеться жонглювати декількома етапами та переконатися, що правильні речі зроблені в потрібний час. Усі, хто написав компілятор, боролися з такими питаннями. Також важко писати програми, які пишуть інші програми, це можуть бути машинні програми (компілятори), SQL запити (маніпуляції з базою даних) або HTML / Сторінки сервера / код Javascript (веб-додатки) та безліч інших програм.


Наскільки я бачу, тож різниця між поетапним обчисленням та частковим оцінюванням - це форма ? (є деякі які можна отримати за допомогою поетапних обчислень, але не з часткової оцінки). ϕ ϕϕ
Та Тхань Дінь

Отже, те, що ви маєте на увазі під частковою оцінкою, є абстракцією над багатоетапним програмуванням, тобто парціальне оцінювання не передбачає багатоетапного програмування, але багатоетапне програмування передбачає часткове оцінювання. Внаслідок чого часткове оцінювання може бути виконане на одній або декількох стадіях, оскільки отримання кривих функціональних мов не обов'язково включає кілька етапів та генерування коду під час виконання, чи не так?
denis631

1
Не зовсім. Частковий оцінювач компілює звичайну програму до двоступеневої програми і потім запускає свій перший етап. У поетапному програмуванні ви самі пишете багатоступеневу програму.
Удай Редді

9

Хоча інші відповіді технічно правильні, я не думаю, що вони дають правильне розуміння того, чому комп'ютерні фахівці зацікавлені в поетапних функціях.

Створюючи поетапні функції, ви визначаєте програми, які генерують програми. Однією з великих цілей сучасної теорії практичної мови є максимальне використання потенціалу. Ми хочемо дати можливість записувати бібліотеки, які не є просто корисними функціями та об'єктами, але допомагають програмістам, надаючи архітектурні конструкції вищого порядку.

Було б чудово, якби ми могли позбутися всього кодового коду. Ми повинні мати можливість мінімізувати мову специфікацій. Якщо ми хочемо, щоб, наприклад, диспетчер, керований подіями, спілкувався з іншими диспетчерами з заданим дизайном потоку, ми повинні мати можливість вказати це компактно, і всі слухачі вводу-виводу та об'єкти і зв'язки черги повинні мати можливість будуватися з цієї специфікації.

Мови домену, як правило, є тими компактними уявленнями, яких ми шукаємо. Коли люди деякий час працюють у домені, мова, якою вони користуються, як правило, знижує більшість дублювання інформації та стає художею специфікацією. Тож ця теорія постановки має тенденцію перетворюватися на систему перекладу з доменних мов на мову виконання.

Компілятори є технічно стаджерами, але це пропускає мету. Мета сучасної постановки - дозволити побудову програм, що будують програми, для максимального використання та автоматизації побудови програм, де це можливо. Було б чудово, якби програмою були одноденні функціональні вимоги.

Див. «Генеративне програмування» Чарнецького та Ейзенекера (ISBN-13: 978-0201309775).


@Raphael: Ось третя глава з основами щодо доменів та повторного використання. Подивіться навіть на оптимізацію, яку ви згадуєте. FFT не робиться поетапно, щоб зробити його швидшим. Це робиться так, що програмісту не потрібно обчислювати таблицю значень кожного разу вручну, копіювати їх у програму та створювати великий список. Це звести до мінімуму виконану роботу та повторно використовувати основні дії. Те саме з циклом розгортання. Роблячи це вручну, повторює інформацію і не може бути використаний повторно.
ex0du5

Ця точка зору DSL, здається, обмежує поетапність до одного рівня (один компілятор DSL всередині програми), правда?
Рафаель

1
@Raphael: Це дійсно залежить від вашої точки зору. Очевидно, що концепція не додає обчислювальної потужності, якщо розглядати її просто як джерело -> виконуваний переклад. Ми могли просто створити компілятор для мови DS і зробити це. Звідки походить сила - це ітерація. Під час побудови бібліотек, які будуть використовуватися та розширені проектами в майбутньому, природні етапи з'являються всередині меж бібліотеки. У вас може бути бібліотека, яка перетворює специфікації об'єкта в джерело для повної серіалізації, а потім ще одну бібліотеку, яка будує транспортний шар, побудований на деяких специфікаціях відправки ...
ex0du5

1
@ Рафаель: Постановка може бути більш природно виконана з декількома етапами. Якщо в одному фрагменті коду вимоги сильно змінюються з часом, де інші набагато стійкіші, можливо, через "нахил шарів" розділити постановку на шари з більш стійкими інтерфейсами. Тоді ви можете менше впливати на систему зі змінами та вшановувати поетапну форму принципу відкритого закриття. Це практичні проблеми, які не мають математичної необхідності, але все базується на практичності. Ми не хочемо єдиної мови компілятора, ми хочемо дозволити еволюцію.
ex0du5

5

Відповідь наводиться в технічній перспективі для відповідної статті [1]. Проблема, що розглядається, - це область напруженості між загальним та конкретним кодом:

Програми можуть бути або загальними, або спеціальними. Код загального призначення має перевагу в тому, що він може бути використаний у різних ситуаціях, тоді як код спеціального призначення може бути написаний таким чином, щоб скористатися унікальними характеристиками середовища виконання та, таким чином, отримати ефективність за рахунок повторного використання.

Звичайно, ми хочемо вирішити цю напругу, тобто досягти загального коду та конкретної реалізації:

Ми можемо задати питання: чи можна написати код таким чином, щоб він був загальним призначенням, але потім він автоматично спеціалізувався на ситуації, що знаходиться під час виконання?

Це породило думку про те, щоб (загальні) програми (пере) писали себе під час виконання під час виконання конкретної ситуації:

Як результат, важливим напрямком досліджень став пошук мови та технології компілятора, що дозволяє програмістам писати код загального призначення, який потім правильно та ефективно перетворюється на високопродуктивний спеціалізований код під час виконання.

Я думаю, JIT JIT - хороший приклад. Одна особлива ідея - багатоступеневе програмування, яке Лі пояснює так:

У цьому напрямі досліджень однією з основних ідей є концепція постановки. Ми уявляємо виконання програми, що протікає в кілька етапів, кожен з яких обчислює значення, які використовуються на пізніших етапах. Тоді ми прагнемо написати програмний код, щоб якимось чином ці етапи стали очевидними. Якщо це досягнуто, ми можемо домогтися компіляції коду пізнішого етапу в генератори коду, які оптимізують результати результатів обчислень на попередньому етапі.

Тобто, «постановка» - це спосіб перегляду відповідних функцій / коду, який ідентифікує фази в обчисленні / виконанні, які можна спростити, знаючи результати попередніх фаз. "Затримка" обчислення, як у першій цитаті у питанні, може бути необхідним побічним ефектом для правильного розділення етапів, але справа не в цьому.

Ромпф та Одерський наводять швидку трансформацію фур'є як приклад, який може бути повчальним.


  1. Лисиця та їжак: технічна перспектива Пітера Лі (2012)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.