这是一个lisp程序,它只是将'a'添加到'b'的绝对值:
(define (a-plus-abs-b a b)
((if (> b 0) + -) a b))
我认为这很美,我正在努力寻找在JavaScript中编写本文的最佳方式。但是我的JavaScript代码并不漂亮:
var plus = function(a,b) {
return a + b;
};
var minus = function(a,b) {
return a - b;
};
var aPlusAbsB = function(a,b) {
return (b > 0 ? plus : minus)(a,b);
}
主要问题是我不能使用+
和-
符号作为对它们真正代表的函数的引用,因为我可以使用lisp。任何人都可以想出一种更优雅的方式做这样的事情,或者我是否达到了语言界限?
显然,我可以这样做:
var aPlusAbsB = function(a,b) {
return a + Math.abs(b);
}
,但这更像是一个思想实验,而不是一个实用的问题。
有没有什么方法可以引用JavaScript语言中的核心函数,就好像它们是用户定义的一样?
答案 0 :(得分:5)
这是一个非常酷的想法 - 对于评估数学表达式非常有用,但是你根本无法将一个运算符(或它背后的逻辑)设置为一个变量。对不起: - )
答案 1 :(得分:5)
这取决于您发现的lisp实现的哪些方面特别美观。我会提出你的建议的另一个版本,我认为通过做一些肮脏的事情,我会更接近你的lisp定义的语法。
// Give ourselves + and - functions to level the playing field with lisp.
Number.prototype['+'] = function(x)this+x;
Number.prototype['-'] = function(x)this-x;
// Now we can have some fun.
var aPlusAbsB = function(a,b) a [b > 0 ? '+' : '-'] (b);
// Some other notable language barrier differences, but not too dissimilar?
// (define (a-plus-abs-b a b) ((if (> b 0) + -) a b))
答案 2 :(得分:3)
虽然没有LISP代码那么优雅,但你可以动态创建一个像操作符一样的函数(在数字上),但事实并非如此。
function op(o) {
return new Function("a", "b", "return a " + o + " b");
}
function aPlusAbsB(a, b) {
return (b > 0 ? op('+') : op('-'))(a, b);
}
此外,我们可以隐藏在if包装器中生成这些内容的复杂性,但这是我能得到的最接近的内容:)
function is(expr, op1, op2) {
return expr ? op(op1) : op(op2);
}
function aPlusAbsB(a, b) {
return (is(b > 0, '+', '-')(a, b));
}
答案 3 :(得分:1)
我认为其他人都先来到这里,但是JS的功能略逊于lisp,运算符不是函数或对象,而是运算符。
答案 4 :(得分:0)
这比你的建议略微漂亮,虽然远不及你的lisp表达概念那么漂亮:
var aPlusAbsB = function(a, b) {
var plus = function(a, b) {
return a + b;
};
var minus = function(a, b) {
return a - b;
};
return (b > 0 ? plus : minus)(a, b);
}
这与计划中的以下内容相同:
(define a-plus-abs-b
(lambda (a b)
(let ((plus (lambda (a b) (+ a b))) (minus (lambda (a b) (- a b))))
(cond ((> b 0) (plus a b))
(else (minus a b))))))
答案 5 :(得分:0)
是的,这不是严格可能的,你能做的最接近的事情就是在里面嵌套加法和减法函数。
var aPlusAbsB = function(a, b) {
return (function(a, b) { b > 0 ? a + b : a - b })(a, b);
}
不完全相同,但它以足够间接的方式完成工作。