我有一个部分完成的解释器,用于词法范围的"纯Lisp"(no set!),它使用按需调用的评估模型,该模型通过简单的缓存进行逐个调用,解释器自然地使用基于环境的评估模型.
评估lambda抽象的标准方法,例如,从正式的paramatres和评估抽象的环境构建一个新环境,并简单地将参数的评估放在它们自己的环境中.然后在新环境中评估抽象主体是行不通的,因为它意味着按值调用语义.
我对这个问题的解决方案是用"查找函数"替换需要"环境"的概念,它只是将符号作为参数,并生成相关的数据.这可以很容易地从一个环境.Lambda应用程序只是通过使用查找函数再次评估正文来完成,该查找函数由定义所在的环境和参数所在的环境构成.它只是在需要时懒洋洋地评估它们.
我想知道的是这个模型的开销是多少,为每个应用程序生成这些查找的成本是多少,这些查找的代码非常大.我知道在Scheme中的lambda应用程序和创建是相当便宜的,许多来源主张广泛使用它们来维护代码的可读性,即使在很多情况下它们会有轻微的开销.但由于lambda应用程序在任何lisp中无处不在,我想知道使用可能不同的模型可以节省多少性能.我尝试在谷歌搜索这个,但我找到的所有需要解释的口译员的模型更加尴尬,但通常是为了适应set!.
我的代码的一些相关部分:
使用查找功能的求值程序:
; evaluates a datum using a lookup
; lookup is a function which takes a symbol as an argument and produces the value
; some sorts of more powerful environment
; if lookup is a standard environment, treats it as such
(define (eval-datum! d lookup)
(cond
((quoted? d) (dequote d)) ; if quoted, just dequote
((hastype d symbol-type) ; symbols ...
(if (procedure? lookup) ; checks if it's an environment …Run Code Online (Sandbox Code Playgroud) 如果像lambda演算或Ocaml这样的curry语言中的CPS如何有意义?从技术上讲,所有函数都有一个参数.所以说我们在一种语言中添加了CPS版本:
cps-add k n m = k ((+) n m)
Run Code Online (Sandbox Code Playgroud)
我们称之为
(cps-add random-continuation 1 2)
Run Code Online (Sandbox Code Playgroud)
这与以下相同:
(((cps-add random-continuation) 1) 2)
Run Code Online (Sandbox Code Playgroud)
我已经看到两个调用不是尾调用,实际上是一个复杂的嵌套表达式,(cps-add random-continuation)返回一个值,即一个消耗数字的函数,然后返回一个消耗另一个数字的函数,然后将两者的总和传递给那个random-continuation.但是我们不能通过简单地将它转换为CPS来解决这个值,因为我们只能给每个函数一个参数.我们需要至少有两个为继续和"实际"论证腾出空间.
还是我完全错过了什么?
我在谷歌上找不到这个(所以也许它不存在),但我基本上想在网络服务器上安装一些东西,这样我就可以在Scheme上运行一个网站,PHP开始惹恼我,我想要要摆脱它,我想要的是:
我不需要任何花哨的库和其他附带的东西,比如CMS'es和what-not,除了对SXML的支持,但我确信我可以找到一个lib,无论如何我可以加载.
R5RS为库语法形式提供了建议的宏定义:
http://schemers.org/Documents/Standards/R5RS/HTML/r5rs-ZH-10.html#%_sec_7.3
其中也以一种非常复杂的方式定义了letrec,当然不是我如何定义它,我会简单地使用:
(define-syntax letrec2
(syntax-rules ()
((letrec2 ((name val) ...) body bodies ...)
((lambda ()
(define name val) ...
body bodies ...)))))
Run Code Online (Sandbox Code Playgroud)
据我所知,letrec的语义,我经常使用它作为命名let.它的工作原理这样,但是我有我与谁认为他们可以否定了狭义相对论或建立语音理论哲学家争论的公平份额,我知道,当你认为你有一个简单的解决一个复杂的问题,它可能错误.必须要有一点,这个宏不能满足letrec的语义,否则他们可能已经使用过了.
在这个定义中,定义是letrec主体的局部定义,它们可以相互引用相互递归,我不太确定是什么(如果有的话)是错误的.
有任何理论上的原因可以阻止这种情况吗?据我所知python模块可以用C编写吗?为什么无法在python 3中调用用python 2编写的函数的原因是什么?
我并不是作为Eq的成员.我的代码:
data Race = Terran | Zerg | Protoss deriving (Eq, Show, Read);
data MU = MU Race Race deriving (Eq, Show);
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我定义了例如(MU Terran Zerg).我想创建一个数据构造函数TvZ,它在intance的各个方面基本相同,所以我可以匹配一个函数模式:
foo TvZ = ...
Run Code Online (Sandbox Code Playgroud)
而不是必须做
foo (MU Terran Zerg) = ...
Run Code Online (Sandbox Code Playgroud)
如果将其分配给变量,则无法执行此操作 tvZ = (MU Terran Zerg)
我想要做的另一件事是做短形式,如在制造型构造T和Terran相同的.
最后一点,medivac速度提升需要一个小的nerf我觉得.
基本上,通常用于通知文件系统更改的 inotify 在 cgroup 虚拟文件系统中不起作用。
本质上,我想要一种在 cgroup 中的进程死亡或分叉时获得类似于 inotify 的通知的方法。我尝试将 inotify 附加到taskscgroup 文件系统内的虚拟文件,但是当进程自行分叉时,只有当 usespace 工具实际手动写入它以影响 cgroup 时,它才会执行任何操作。
我不确定这与"程序语言设计"相反的"编程"究竟有多少.但问题是:
说,为了简单起见,我们有两个'特殊'列表/数组/向量/为了简单我们只称为'端口',一个叫做stdIn另一个stdOut.这些概念上分别代表
在Haskell启发的伪代码中,应该可以创建这个完全声明性的程序:
let stdOut = ["please input a number",
"and please input another number",
"The product of both numbers is: " ++ stdIn[0] * stdIn[1]]
Run Code Online (Sandbox Code Playgroud)
哪个会做到预期,要求两个数字,并打印他们的产品.诀窍是stdOut表示在程序完成时写入终端的字符串列表,stdIn是输入字符串列表.键入错误以及需要一些安全措施才能在输入新行后仅打印下一行这一事实为了简单起见而留在这里,它可能很容易解决.
所以,在我实施这个想法之前,我忽略了它有什么陷阱吗?我不知道已经存在类似的结构,所以不考虑我忽略了一个明显的陷阱是天真的.
否则,我当然知道:
let stdOut = [stdIn[50],"Hello, World!"]
Run Code Online (Sandbox Code Playgroud)
如果这些结果需要以与上述类似的方式交织,那将是一个错误.
functional-programming side-effects logic-programming declarative-programming
scheme ×3
haskell ×2
cgroups ×1
currying ×1
inotify ×1
interpreter ×1
linux ×1
lisp ×1
macros ×1
module ×1
ocaml ×1
performance ×1
python ×1
side-effects ×1
sxml ×1