我在The Three Projections of Doctor Futamura读了Dan Piponi的优秀博客文章。在文章的最后,他有一个附录,其中包含了Haskell中Futamura投影的证据。但是,我发现他的文章缺乏有关所涉及语言的信息。为了使Futamura预测有效,专业化师的源语言,目标语言和对象语言必须具备哪些内容?例如,如果我在Haskell中将Haskell写入LLVM专用器,那么Futamura投影会起作用吗?如果您编写一个Haskell程序来证明这一点就像Dan Piponi在他的文章中所做的那样会很有帮助。
答案 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预测比原先认为的更容易,也更有价值。我还没有对此进行测试,所以请耐心等待。