最近我一直在编写一个简单的编译器来更好地理解编译器概念.作为stackoverfolow的勤奋读者,似乎有一种共识,即在函数式语言中编写编译器比命令式编写器更容易.为此,我想我会尝试杀死两只鸟,并在F#中编写一个编译器来学习一种函数式语言并同时编写一个编译器.
我一直在阅读龙书,并决定从F#手写的递归下降解析器开始.然而,龙书几乎所有的代码样本都是命令式的.例如,匹配令牌功能通过副作用完成其工作的重要部分.
所以我的问题是什么是更传统的解析功能方法(即几个副作用)看起来像什么?我知道Haskell编译器(GHC)是用Haskell编写的,但我希望能够理解一些更小,更容易理解的代码示例.
第二,尝试采用功能性方法进行解析是否值得,或者它是否真的在对功能语言闪耀的中间代码进行优化,而我还没有到达那里?也就是说,我是否应该使用命令式样式在F#中进行解析并稍后切换到更具功能性的方法?
所以Mathematica与lisp的其他方言不同,因为它模糊了函数和宏之间的界限.在Mathematica中,如果用户想要编写数学函数,他们可能会使用模式匹配,f[x_]:= x*x
而不是f=Function[{x},x*x]
两者都会在调用时返回相同的结果f[x]
.我的理解是第一种方法相当于一个lisp宏,并且由于语法更简洁,我的经验受到青睐.
所以我有两个问题,执行函数与模式匹配/宏方法之间是否存在性能差异?虽然函数实际上转换为某些版本的宏以允许实现的功能,但我的一部分不会感到惊讶Listable
.
我关心这个问题的原因是因为最近关于试图在大型程序中捕获Mathematica错误的问题(1) (2).如果大多数计算是根据函数定义的,那么在我看来,跟踪评估的顺序和错误发生的位置比在连续应用宏来重写输入后尝试捕获错误更容易/模式.
我真的想更好地理解在PostgreSQL中创建一个在windows上运行的UDF所涉及的内容.我做了一些关于如何创建UDF的搜索,但没有找到如何在窗口上操作的示例.
为此,我希望有人愿意分享如何编写UDF(可以是C,pl/SQL或PostgreSQL支持的任何过程语言)的代码,以计算窗口中数字的运行平均值.我意识到有一些方法可以通过应用标准的平均聚合函数和窗口语法(我相信语法之间的行)来实现这一点,我只是要求这个功能,因为我认为这是一个很好的简单例子.此外,我认为如果存在平均函数的窗口版本,那么数据库可以保持运行总和和观察计数,并且在每次迭代时不会总结几乎相同的行集.
最近我一直在研究Mathematica的模式匹配和术语重写如何在编译器优化中得到很好的利用......试图高度优化作为循环内部部分的短代码块.减少评估表达式所需工作量的两种常用方法是识别出现多次的子表达式并存储结果,然后在后续点使用存储的结果来节省工作.另一种方法是尽可能使用更便宜的操作.例如,我的理解是,取平方根比加法和乘法需要更多的时钟周期.为了清楚起见,我感兴趣的是评估表达式所需的浮点运算成本,而不是Mathematica评估它需要多长时间.
我的第一个想法是,我将解决使用Mathematica的简化功能开发的问题.可以指定复杂度函数来比较两个表达式的相对简单性.我打算使用权重为相关算术运算创建一个,并为表达式添加LeafCount以考虑所需的赋值操作.这解决了力量方面的减少,但它消除了我绊倒的常见子表达式.
我正在考虑将公共子表达式消除添加到简化使用的可能的转换函数中.但是对于一个大表达式,可能有许多可能被替换的子表达式,并且在看到表达式之前不可能知道它们是什么.我编写了一个函数来提供可能的替换,但是看起来你指定的转换函数需要返回一个可能的转换,至少从文档中的示例来看.关于如何解决这个限制的任何想法?有没有人更好地了解简化如何使用可能暗示前进方向的转换函数?
我想,在幕后,Simplify正在做一些动态编程,尝试对表达式的不同部分进行不同的简化,并返回具有最低复杂度得分的那个.使用常见的代数简化(例如factor和collect),我是否会更好地尝试自己动态编程?
编辑:我添加了生成可能删除的子表达式的代码
(*traverses entire expression tree storing each node*)
AllSubExpressions[x_, accum_] := Module[{result, i, len},
len = Length[x];
result = Append[accum, x];
If[LeafCount[x] > 1,
For[i = 1, i <= len, i++,
result = ToSubExpressions2[x[[i]], result];
];
];
Return[Sort[result, LeafCount[#1] > LeafCount[#2] &]]
]
CommonSubExpressions[statements_] := Module[{common, subexpressions},
subexpressions = AllSubExpressions[statements, {}];
(*get the unique set of sub expressions*)
common = DeleteDuplicates[subexpressions];
(*remove constants from the list*)
common = Select[common, LeafCount[#] > 1 &];
(*only …
Run Code Online (Sandbox Code Playgroud)