Я думаю, що багато реалізаторів компіляторів для типових імперативних мов просто не були знайомі з методами компіляції на основі CPS та CPS. У спільноті функціонального програмування як компіляція на базі CPS, так і CPS є дуже відомими методами - остання з роботи Гая Стіла. Тим не менш, навіть у спільноті FP більшість компіляторів не використовують методи компіляції на основі CPS, якщо мова не підтримує операторів управління, як call/cc
. Використовується щось подібне до адміністративної нормальної форми (ANF) (іноді її також називають монадійною нормальною формою, яка тісно пов'язана з причин, які стануть зрозумілими), яка має ще більш жорсткі стосунки до SSA, ніж CPS .
Якщо я добре пам’ятаю, адміністративна нормальна форма отримала свою назву від того, що компіляція на основі CPS може призвести до бета-перенастроювання проміжного коду, який не відповідав нічого у вихідному коді. Їх називали "адміністративними переробленнями". Вони можуть скоротитися під час компіляції, але було проведено велику кількість досліджень щодо виконання перетворення CPS, яке б виводило код без адміністративних перестановок. Мета цього полягала в тому, щоб випускати продукцію в нормальній формі, де всі "адміністративні" зміни були зменшені, і це було походженням адміністративної нормальної форми. Зрозуміло, що не було багато користі для того, щоб сприймати це як (n оптимізацію а) двоетапного процесу: перетворення CPS, зменшення адміністративних оновлень. Зокрема, нормальна адміністративна форма виглядає скоріше як монадійський стиль, як це практикується (вручну), особливо в Хаскеллі. Перетворення CPS можна розуміти як перетворення в монадійний стиль, коли ви просто використовуєте монаду CPS (тому дійсно існує багато способів "перетворити" в монадійний стиль, що відповідає різним замовленням на оцінку). Взагалі, однак, ви можете використовувати зовсім іншу монаду, і тому перетворення в монадійський стиль і, таким чином, адміністративно нормальна форма насправді не пов'язане зокрема з CPS.
Тим не менш, були деякі переваги для CPS порівняно з ANF. Зокрема, існували певні оптимізації, які ви можете зробити у CPS за допомогою лише стандартних оптимізацій, таких як бета-скорочення, які вимагали (здавалося б) спеціальних правил для ANF. З монадичної точки зору, ці правила відповідають конверсіям, що здійснюють маршрути. Підсумок тепер є теорія, яка може пояснити, які правила слід додати та чому. Недавня стаття дає (нове і) досить чіткий опис цього (з логічної точки зору) і пов'язаний з ним розділ роботи служить короткої , але пристойному обстеження і посилання в літературу за темами , які я згадую.
Проблема з CPS пов'язана з однією з головних її переваг. Трансформація CPS дозволяє вам реалізувати такі оператори керування call/cc
, але це означає, що кожен не локальний виклик функції в проміжному коді CPS повинен розглядатися як потенційно виконуючий керуючі ефекти. Якщо у вашій мові є оператори керування, то це саме так, як і повинно бути (хоча навіть тоді більшість функцій, ймовірно, не виконують жодних шенагіганів управління). Якщо у вашій мові не входять оператори управління, то існують глобальні інваріанти щодо використання продовжень, які не очевидні локально. Це означає, що є оптимізація, яка не є голосною для виконання загального коду CPS, що було б здорово виконувати на цьому особливо добре сприйнятому використанні CPS. Один із способів цього проявляється взміна точності даних та аналіз потоків контролю . (Трансформація CPS в деяких випадках допомагає, шкодить іншим, хоча способи, які вона допомагає, здебільшого пояснюються дублюванням, а не самим аспектом CPS.) 1 Ви, звичайно, можете додати правила та коригувати аналізи, щоб компенсувати це (тобто використовувати глобальні інваріанти), але потім ви частково перемогли одну з головних переваг компіляції на основі CPS, яка полягає в тому, що багато (здавалося б) спеціальні оптимізації перетворюються на особливі випадки оптимізації загального призначення (зокрема бета-скорочення ).
Зрештою, якщо у вашій мові немає операторів управління, зазвичай не так багато причин використовувати схему компіляції на основі CPS. Як тільки ви компенсуєте проблеми, про які я згадував вище, ви зазвичай усунули переваги компіляції на основі CPS і створили щось еквівалентне тому, що не використовуєте CPS. У цей момент CPS просто робить проміжний код із закругленим виглядом для не дуже великої вигоди. Аргумент для компіляції на основі CPS з 2007 року вирішує деякі з цих питань та представляє деякі інші переваги, використовуючи іншу форму перетворення CPS. Речі, які приносить папір, частково охоплені документом (2017), про який я згадував раніше.
1 Чи не робить еквівалентність між SSA та CPS це більш-менш неможливим? Ні. Одне з перших речей, в якому вводиться ця еквівалентність, полягає в тому, що еквівалентність не працює для довільного коду CPS, але вона працює для виведення перетворення CPS (який вони визначають) для мови без операторів управління.