Haskell中Futamura预测的证明

时间:2017-09-01 02:32:36

标签: haskell compiler-construction interpreter

我在The Three Projections of Doctor Futamura读了Dan Piponi的优秀博客文章。在文章的最后,他有一个附录,其中包含了Haskell中Futamura投影的证据。但是,我发现他的文章缺乏有关所涉及语言的信息。为了使Futamura预测有效,专业化师的源语言,目标语言和对象语言必须具备哪些内容?例如,如果我在Haskell中将Haskell写入LLVM专用器,那么Futamura投影会起作用吗?如果您编写一个Haskell程序来证明这一点就像Dan Piponi在他的文章中所做的那样会很有帮助。

1 个答案:

答案 0 :(得分:15)

是的,当且仅当专业化师的源语言和对象语言相同时,Futamura预测才会起作用。这是因为如果专门化程序使用与其可读取的语言相同的语言编写,则它只能应用于自身。但是,专门化程序的目标语言与其他两种语言无关。这具有重要的后果,我将在本回答中稍后讨论。

为了证明我的假设,我将引入一个新的符号来基于tombstone diagrams松散地描述程序。墓碑图(或T图)是编译器和其他相关metaprograms的图形表示。它们用于说明和推理程序从源语言(T的左侧)到目标语言(T的右侧)的转换,如在对象语言(T的底部)中实现的。让我们扩展T图的概念以适用于所有程序:

α → β : ℒ -- A program is a function from α to β as implemented in language ℒ.

对于元程序αβ本身就是程序:

(α → β : ) × α → β :  -- An interpreter for language  as implemented in .
(α → β : ) → (α → β : ) :  -- A compiler from  to  as implemented in .
(ι × α → β : ) × ι → (α → β : ) :  -- A self-hosting specializer from  to .
(ι × α → β : ) → (ι → (α → β : ) : ) :  -- A compiler compiler from  to .

这种表示法可以直接转换为Haskell中的类型定义。有了这个,我们现在可以在Haskell中编写关于语言的Futamura预测的证明:

{-# LANGUAGE RankNTypes #-}

module Futamura where

newtype Program a b language = Program { runProgram :: a -> b }

type Interpreter source object = forall a b.       Program (Program a b source, a) b object
type Compiler    source target = forall a b.       Program (Program a b source) (Program a b target) target
type Specializer source target = forall input a b. Program (Program (input, a) b source, input) (Program a b target) source
type Partializer source target = forall input a b. Program (Program (input, a) b source) (Program input (Program a b target) target) target

projection1 :: Specializer object target -> Interpreter source object -> Program a b source -> Program a b target
projection1 specializer interpreter program = runProgram specializer (interpreter, program)

projection2 :: Specializer object target -> Interpreter source object -> Compiler source target
projection2 specializer interpreter = runProgram specializer (specializer, interpreter)

projection3 :: Specializer source target -> Partializer source target
projection3 specializer = runProgram specializer (specializer, specializer)

我们使用RankNTypes语言扩展来隐藏类型级别的机制,使我们能够专注于所涉及的语言。将专门化器应用于自身也是必要的。

在上述计划中,第二项预测特别令人感兴趣。它告诉我们,给定一个自托管Haskell到LLVM专用器,我们可以将它应用于任何用Haskell编写的解释器,以获得一些源语言来获取LLVM编译器。这意味着我们可以用高级语言编写解释器,并使用它来生成以低级语言为目标的编译器。如果特化器有任何好处,那么生成的编译器也会非常好。

另一个值得注意的细节是自托管专用程序与自托管编译器非常相似。如果您的编译器已经执行了部分评估,那么将其转换为专用程序不应该太多工作​​。这意味着实施Futamura预测比原先认为的更容易,也更有价值。我还没有对此进行测试,所以请耐心等待。