Stalin是Scheme的优化编译器,它执行整个程序的静态分析,并使用该分析的结果生成极其高效的代码.斯大林利用大量的静态分析技术.它执行一种新形式的多变量流分析,使用迭代单变量流分析来执行流向分裂:克隆程序的专用副本和将目标分配到这些克隆的每个调用点.它使用流量分析的结果执行寿命分析,逃逸分析,点分析和必须别名分析.这些分析支持一种新颖的轻量级闭包转换形式,它消除了大多数闭包槽,使用诸如可变全球化和本地化之类的技术,压缩静态后链,并且通常从程序中消除大多数闭包.它还使用上述分析来支持基于流的区域存储管理,其中运行时垃圾收集在每个抽象值和每个程序点的基础上被静态分配和释放替换.它还使用Screamer开创的技术扩展来执行流向轻量级CPS转换,以支持极其高效的一流延续.最后,它支持流向内联和低级表示选择,以在每个抽象值和每个程序点的基础上选择标记的实现(或非实现),标记检查和标记分派.这消除了大多数运行时标记,标记检查,标记,标记剥离,标记调度,装箱和从程序中取消装箱.这些分析和优化允许斯大林生成极其高效的代码,其性能优于所有其他Scheme编译器,范围在2到100之间,特别是对于数字密集型代码.斯大林经常生成的代码优于手写的c和Fortran代码.
我能够找到以下关于闭包/函数调用实现的非常有趣的论文:Flow-Directed Lightweight Closure Conversion.我还通过电子邮件向作者询问了关于其他主题的论文,这些论文被提到将在封闭转换论文中写出:
Siskind,JM 2000a.流向轻量CPS转换.在筹备.
Siskind,JM 2000b.流向多变量.在筹备.
Siskind,JM 2000c.流向定向表示选择.在筹备.
Siskind,JM 2000d.流向存储管理.在筹备
不幸的是,他从来没有写过那些论文.我的问题是:是否有任何替代或相关的论文涉及这些主题?我非常有兴趣了解Stalin(或其他编译器)如何编译如垃圾收集,动态类型,支持第一类函数甚至是第一类延续的Scheme这样的高级语言,可以静态编译为如此高效的代码.
许多静态类型语言具有参数多态性.例如在C#中,可以定义:
T Foo<T>(T x){ return x; }
Run Code Online (Sandbox Code Playgroud)
在呼叫站点中,您可以:
int y = Foo<int>(3);
Run Code Online (Sandbox Code Playgroud)
这些类型有时也像这样写:
Foo :: forall T. T -> T
Run Code Online (Sandbox Code Playgroud)
我听过有人说"forall就像类型级别的lambda抽象".所以Foo是一个函数,它接受一个类型(例如int),并产生一个值(例如int - > int类型的函数).许多语言推断出类型参数,因此您可以编写Foo(3)而不是Foo<int>(3).
假设我们有一个f类型的对象forall T. T -> T.我们可以用这个对象做的是首先通过Q写入传递它f<Q>.然后我们得到一个类型的值Q -> Q.但是,某些f是无效的.例如f:
f<int> = (x => x+1)
f<T> = (x => x)
Run Code Online (Sandbox Code Playgroud)
因此,如果我们"调用",f<int>那么我们会返回一个带有类型的值,int -> int一般来说,如果我们"调用",f<Q>那么我们会返回一个带有类型的值Q -> Q,这样就很好了.但是,人们普遍认为这f不是一种有效的类型forall T. T -> T,因为它根据您传递的类型做了 …
ocaml haskell types existential-type parametric-polymorphism
依赖类型系统似乎支持ML模块系统的一些用途.你从模块系统中获得了什么,你没有从依赖记录中获得?
模块〜记录
签名〜记录类型
functor~记录功能
具有抽象类型组件的模块〜具有类型字段的依赖记录
我对它作为模块系统的工作情况感兴趣,以及是否以及如何集成应用程序仿函数和mixin等功能.
将垃圾收集语言编译为C时,垃圾收集的技术有哪些?我知道两个:
维护一个影子堆栈,在数据结构中显式保存所有根
使用像Boehm这样的保守垃圾收集器
第一种技术很慢,因为你必须维护阴影堆栈.每次调用函数时,都需要将局部变量保存在数据结构中.
第二种技术也很慢,并且由于使用了保守的垃圾收集器,本质上不会回收所有垃圾.
我的问题是:在编译为C时,垃圾收集的最新技术是什么.注意,在C语言编程时,这并不意味着进行垃圾收集的方便方式(这是Boehm垃圾收集器的目标),只是一种方式编译为C时进行垃圾收集.
我想创建一个具有子窗口小部件的窗口小部件,我可以动态更改它.这是我尝试过的:
import sys
from PySide.QtCore import *
from PySide.QtGui import *
class Widget(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
self.setLayout(QVBoxLayout())
self.child = QLabel("foo", self)
self.layout().addWidget(self.child)
def update(self):
self.layout().removeWidget(self.child)
self.child = QLabel("bar", self)
self.layout().addWidget(self.child)
app = QApplication(sys.argv)
widget = Widget()
widget.show()
widget.update()
app.exec_()
Run Code Online (Sandbox Code Playgroud)
问题是,这实际上并没有在视觉上删除"foo"标签.它仍然呈现在"酒吧"之上.问题的屏幕截图.如何删除旧窗口小部件以便仅显示新窗口小部件?
我知道我可以更改标签的text属性.这不是我想要的应用程序,我需要更改实际的小部件(到不同的小部件类型).
有两种数据类型:任务和操作.一个动作需要花费一定的时间来完成,这个动作包含一组任务.任务有一系列操作,我们的工作是选择其中一个.所以:
class Task { Set<Action> choices; }
class Action { float time; Set<Task> dependencies; }
Run Code Online (Sandbox Code Playgroud)
例如,主要任务可能是"获得房子".这项任务可能采取的行动:"买房子"或"盖房子"."建造一栋房子"的行动需要花费10个小时,并且具有依赖性"获取砖块"(可能花费6个小时)和"获得水泥"(花费9个小时)等等.
的总时间是来执行所需的操作的所有时间(在此情况下10 + 6 + 9小时)的总和.我们希望选择总时间最短的行动.
请注意,依赖关系可以是菱形的.例如,"获取砖块"可能需要"获取汽车"(运输砖块)和"获取水泥"也需要汽车.即使你做的"获取砖头"和"获取水泥"你只需要计算才能得到一辆汽车的时间一次.
另请注意,依赖项可以是循环的.例如"Money" - >"Job" - >"Car" - >"Money".这对我们来说没问题,我们只选择所有"钱","工作"和"汽车".总时间只是这三件事的时间总和.
数学描述:
让我们actions选择行动.
valid(task) = ?action ? task.choices. (action ? actions ? ?tasks ? action.dependencies. valid(task))
time = sum {action.time | action ? actions}
minimize time subject to valid(primaryTask)
Run Code Online (Sandbox Code Playgroud)
我对最佳解决方案感兴趣,但也对近似解决方案感兴趣.也许某种动态编程可以帮到那里?如果问题是树形结构,那么动态编程可以在多项式时间内给出最优解,但是钻石结构似乎使问题更加困难.如果你有一个算法,但是如果有循环则不起作用,请发布它!我可能仍然可以从中学到很多东西.

框表示任务,圆圈表示动作(执行动作的时间在圆圈中).如果该任务是该操作的依赖项,则该操作对任务具有一行.以下是关于图片的问题描述:如果选择了矩形(=任务),则必须选择其中一个圆(=动作).如果选择了圆,则必须选择所有连接的矩形.目标是最小化所选圈子中的数字总和.
在这种情况下,最佳解决方案是在顶部任务中选择时间2的操作,在底部任务中选择时间1的操作.总时间为2 + 1 + 1 = 4.在这种情况下,有2个最佳解决方案.第二种解决方案是在顶部任务中选择时间为3的操作,在右下角任务中选择时间为1的操作.总时间再次为3 + 1 = 4.如果我们在顶部任务中选择时间3的动作,则不必执行左下角任务,因为动作与时间3和左下角任务之间没有线.
我为糟糕的绘画道歉;)还有两个例子(每个例子的最佳解决方案用蓝色表示,主要任务用灰色表示):

这是一个简单的测试应用程序(在F#中,但我检查过,在C#中出现同样的问题):
let but = new Button(Content = "click me")
but.Click.Add(fun e -> printfn "clicked")
[<STAThread>]
do (new Application()).Run(new Window(Content = but))
Run Code Online (Sandbox Code Playgroud)
在VS 11预览中运行此操作时(无论哪个.NET版本),单击后约0.5秒会出现"单击"消息.在C#中也是如此.当我转到存储项目的文件夹并在VS外部运行.exe时,单击后会立即显示该消息.显然,调试工具正在大大减缓这种特殊情况.为什么这个以及可以做些什么呢?
如何按名称加载WinRT程序集?当我执行以下操作时:
(new TextBlock()).GetType().GetTypeInfo().Assembly
Run Code Online (Sandbox Code Playgroud)
然后我得到程序集Windows.UI.Xaml.Controls.但是,如果我尝试按名称加载它:
var name = new AssemblyName {
Name = "Windows.UI.Xaml.Controls",
Version = new Version(255, 255, 255, 255),
ContentType = AssemblyContentType.WindowsRuntime
};
Run Code Online (Sandbox Code Playgroud)
然后它说"操作不受支持".即使我这样做也会发生这种情况:
var name = (new TextBlock()).GetType().GetTypeInfo().Assembly.GetName();
Assembly.Load(name);
Run Code Online (Sandbox Code Playgroud)
如何按名称获取WinRT程序集?
假设我们有一个带有一个源的DAG.我想找到节点n,使得来自源的任何完整路径贯穿n(即n支配所有接收器).换句话说:如果我们删除了所有的成功者n,那么所有路径都将以此结束n.问题是节点在DAG中逐渐标记为已删除.当节点被标记为已删除时,其他节点可以开始满足上述属性.如何才能有效地检测到这种情况?
积分如果数据结构,可以在比每一个的源极分别运行算法用于单个源更有效的方式与多个源执行此操作.
以下是我想对以集合为元素的假设集合数据结构执行的操作:
所有有问题的集合都是已知有限集合的子集,比如 {0..10^4}。
有没有办法有效地做到这一点?