lisp中的列表是一系列cons单元格,但在Tcl中,列表是一个用空格分隔元素的字符串.为了将代码从lisp转换为tcl,可以简单地使用lisp列表并将它们转换为Tcl列表.然而,这会导致副作用缺陷单元没有遇到Tcl代码.例如,在lisp中考虑以下代码:
(setq a (list 1 2 3 4))
(let ((b a)
(a (cddr a)))
(declare (special a b))
(setf (cadr b) ‘b)
(setf (cadr a) ‘d)
(print a))
(print a)
;; Results in:
(3 d)
(1 b 3 d)
Run Code Online (Sandbox Code Playgroud)
是否有一个Tcl包可以在Tcl中更好地模拟lisp列表?这样的软件包是否可以轻松转换为常规Tcl列表?
上面的代码在Tcl中使用这样的包可能是什么样的?
是否有可能(在C#中)使checked(...)表达式具有动态"范围"以进行溢出检查?换句话说,在以下示例中:
int add(int a, int b)
{
return a + b;
}
void test()
{
int max = int.MaxValue;
int with_call = checked(add(max, 1)); // does NOT cause OverflowException
int without_call = checked(max + 1); // DOES cause OverflowException
}
Run Code Online (Sandbox Code Playgroud)
因为在表达式中checked(add(max, 1)),函数调用会导致溢出,而不会OverflowException抛出,即使在表达式的动态范围内存在溢出checked(...).
有没有办法让两种方式评估int.MaxValue + 1投掷OverflowException?
编辑:嗯,要么告诉我是否有办法,或者给我一个更好的方法来做到这一点(请).
我认为我需要这个的原因是因为我的代码如下:
void do_op(int a, int b, Action<int, int> forSmallInts, Action<long, long> forBigInts)
{
try
{
checked(forSmallInts(a, b));
} …Run Code Online (Sandbox Code Playgroud) 在过去,Emacs不支持词法范围.我想知道当时人们如何处理动态范围的特定陷阱.
假设Alice编写的命令my-insert-stuff依赖于fp-repeat定义的函数fp.el(我们假设它是一个为Bob编写的函数式编程提供大量函数的库),并且假设fp-repeat是多次重复调用函数.
init.elAlice的部分内容:
(require 'fp)
(defun my-insert-stuff ()
(interactive)
;; inserts "1111111111\n2222222222\n3333333333" to current buffer
(dolist (i (list "1" "2" "3"))
(fp-repeat 10
(lambda ()
(insert i)))
(insert "\n")))
Run Code Online (Sandbox Code Playgroud)
fp.elBob的部分内容:
(defun fp-repeat (n func)
"Calls FUNC repeatedly, N times."
(dotimes (i n)
(funcall func)))
Run Code Online (Sandbox Code Playgroud)
爱丽丝很快发现她的命令不像她预期的那样有效.那是因为Alice的使用i和Bob的使用i相撞.在过去,爱丽丝或/和鲍勃可以做些什么来阻止这种碰撞的发生?
也许Bob可以将文档字符串更改为
"Calls FUNC repeatedly, N times.
Warning: Never use i, n, func in FUNC body as nonlocal variables."
Run Code Online (Sandbox Code Playgroud) 我使用动态作用域来模拟JavaScript 中的指针,如下所示:
var ptr = (function () {
var ptr = "(" + String(function (value) {
if (value === void 0) return upvalue;
else upvalue = value;
}) + ")";
return function (upvalue) {
return ptr.replace(/upvalue/g, upvalue);
};
}());
function swap(xptr, yptr) {
var t = xptr();
xptr(yptr());
yptr(t);
}
var x = 2;
var y = 3;
alert([x, y]);
swap(eval(ptr("x")), eval(ptr("y")));
alert([x, y]);
Run Code Online (Sandbox Code Playgroud)
有没有其他方法可以达到相同的结果(即不诉诸eval)?这似乎是太多的样板文件。
在阅读了有关声明SPECIAL 的文档、特殊运算符LET、宏DEFVAR以及 StackOverflow 上关于 Common Lisp 中动态与词法范围的几个问题之后,例如,this 之后,我仍然无法理解以下行为在 SBCL 中评估这些形式。
;; x is a free variable
CL-USER> (defun fn ()
(print x))
; in: DEFUN FN
; (PRINT X)
;
; caught WARNING:
; undefined variable: X
;
; compilation unit finished
; Undefined variable:
; X
; caught 1 WARNING condition
FN
CL-USER> (describe 'x)
COMMON-LISP-USER::X
[symbol]
; No value
CL-USER> (let ((x 'dinamic_1st_binding))
(declare (special x))
(print x)
(fn)
(let …Run Code Online (Sandbox Code Playgroud) 我在(常见)lisp中看到两种不同的"输出"函数模式:
(defun implicit ()
(format t "Life? Don't talk to me about life!"))
(defun explicit (stream)
(format stream "This will all end in tears."))
(defun test-im-vs-ex-plicit ()
(values
(with-output-to-string (stream)
(let ((*standard-output* stream))
(implicit)))
(with-output-to-string (stream)
(explicit stream))))
Run Code Online (Sandbox Code Playgroud)
是否使用动态范围,如在implicit被认为是不好的做法,或者这是一个普遍接受的动态范围使用?请注意,我假设这是用于构建复杂输出的DSL,如HTML,SVG,Latex等等,除了生成打印表示之外,预计不会做任何不同的事情.
是否 - 除了样式 - 任何重要的差异,例如在性能,并发性或其他方面?
design-patterns coding-style anti-patterns common-lisp dynamic-scope
是否有一种干净的方式来实现动态范围,以"达到"宏调用?也许更重要的是,即使有,也应该避免?
这是我在REPL中看到的内容:
user> (def ^:dynamic *a* nil)
> #'user/*a*
user> (defn f-get-a [] *a*)
> #'user/f-get-a
user> (defmacro m-get-a [] *a*)
> #'user/m-get-a
user> (binding [*a* "boop"] (f-get-a))
> "boop"
user> (binding [*a* "boop"] (m-get-a))
> nil
Run Code Online (Sandbox Code Playgroud)
这个m-get-a宏不是我的实际目标,它只是我遇到的问题的一个简化版本.我花了一段时间才意识到,因为我一直在调试macroexpand,这使得一切看起来都很好:
user> (binding [*a* "boop"] (macroexpand '(m-get-a)))
> "boop"
Run Code Online (Sandbox Code Playgroud)
在外部调用上执行macroexpand-all(使用clojure.walk)binding会让我相信"问题"(或特征,视情况而定)是(m-get-a)在动态绑定之前进行评估:
user> (macroexpand-all '(binding [*a* "boop"] (f-get-a)))
> (let* []
(clojure.core/push-thread-bindings (clojure.core/hash-map #'*a* "boop"))
(try (f-get-a) (finally (clojure.core/pop-thread-bindings))))
user> (macroexpand-all …Run Code Online (Sandbox Code Playgroud) 据我所知,动态变量在运行时被查找.我想使用它们来启用类似于球拍参数的参数化.
为此,我必须设置一个应该可以覆盖的默认值,但不一定是可更改的.我目前的方法相当简单:
my $*param ::= 42;
sub parameterized-function { say $*param };
parameterized-function();
do {
my $*param ::= 15;
parameterized-function();
}
Run Code Online (Sandbox Code Playgroud)
哪个工作正常 - 除了它在外部范围引入参数的名称.除了感觉不整洁之外,my $*param = 15;如果在文件级别上使用,这会产生导致混乱的副作用.
我想要做的是检查参数是否已在调用堆栈上定义,顺序如下:
sub parameterized-function { if defined($*param) { say 42 } else { say $*param } };
Run Code Online (Sandbox Code Playgroud)
那么,是否有可能进行这样的检查,如果是这样,它是如何完成的?
在阅读一些lisp历史时,从LISP 1到LISP 1.5,我遇到了这个功能:
(define (testr x p f u)
(if (p x)
(f x)
(if (atom? x)
(u)
(testr (cdr x)
p
f
(lambda ()
(testr (car x) p f u))))))
Run Code Online (Sandbox Code Playgroud)
麦卡锡认为,"困难在于当内部递归发生时,car [x]所需的值是外部值,但实际使用了内部值.在现代术语中,需要词法范围,并获得动态范围. ".
我无法弄清楚他所指的是什么"外部价值"和"内在价值",也无法看到在使用动态范围进行评估时这个函数是如何行为不当的.我能理解lambda是否有些阴影'x',但它是零参数的函数.
(实际上很难找到这个功能,因为它似乎从网页本身中遗漏了.只是在浏览了images.tex文件之后:http://www-formal.stanford.edu/jmc/history/lisp /images.tex,我发现它).
在下面的代码中,2打印出来.
int x = 1;
int f(int y)
{
return x;
}
int main() {
x = 2;
printf("%d", f(0));
}
Run Code Online (Sandbox Code Playgroud)
如果我们在C中有静态作用域,它会怎么样?为什么不1打印?
印花 2在这种情况下不是动态范围,是吗?
我认为在静态作用域中它应该使用最近的x到函数定义.
我正在尝试编写一个perl脚本,该脚本调用在其他地方(由其他人)编写的函数,该函数操作我脚本范围内的一些变量.假设脚本是main.pl并且函数在那里funcs.pm.我main.pl看起来像这样:
use warnings;
use strict;
package plshelp;
use funcs;
my $var = 3;
print "$var\n"; # <--- prints 3
{ # New scope somehow prevents visibility of $pointer outside
local our $pointer = \$var;
change();
}
print "$var\n"; # <--- Ideally should print whatever funcs.pm wanted
Run Code Online (Sandbox Code Playgroud)
出于某种原因,使用会local our $pointer;阻止$pointer范围外的可见性.但是如果我只是使用our $pointer;,变量可以在main.pl使用范围之外看到$plshelp::pointer(但不是在funcs.pm,所以无论如何它都是无用的).作为附注,有人可以解释一下吗?
funcs.pm 看起来像这样:
use warnings;
use strict;
package plshelp;
sub change
{
${$pointer} …Run Code Online (Sandbox Code Playgroud)