Получение ссылки на Функциональный объект JavaScript позади оператора

Вот процедура шепелявости, которая просто добавляет к абсолютному значению '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);
}

Основная проблема состоит в том, что я не могу использовать + и - символы как ссылки на функции, которые они действительно представляют, как я могу с шепелявостью. Кто-либо может придумать более корректный способ сделать что-то вроде этого, или я поразил границу языка?

Очевидно, я могу сделать это:

var aPlusAbsB = function(a,b) {
    return a + Math.abs(b);
}

, но это - больше мысленного эксперимента, чем прагматический вопрос.

Есть ли какой-либо способ, которым я могу получить ссылку на базовые функции на языке сценариев JavaScript так же, как если бы они были пользовательскими?

7
задан Vatine 10 March 2010 в 11:16
поделиться

6 ответов

Это очень крутая идея - она ​​отлично подходит для оценки математических выражений, но вы просто не можете установить оператор (или логику, стоящую за ним) для переменной. Извините: -)

5
ответ дан 6 December 2019 в 15:20
поделиться

Это зависит от того, какие аспекты реализации 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))
5
ответ дан 6 December 2019 в 15:20
поделиться

Я думаю, что все остальные попали сюда первыми, но JS немного менее функционально, чем lisp, операторы - это не функции или объекты, а операторы.

1
ответ дан 6 December 2019 в 15:20
поделиться

Это немного красивее, чем ваше предложение, хотя и далеко не так красиво, как ваше шепелявое представление концепции:

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))))))
0
ответ дан 6 December 2019 в 15:20
поделиться

Хотя это не так элегантно, как код 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
ответ дан 6 December 2019 в 15:20
поделиться

Да, это не совсем возможно, самое близкое, что вы можете сделать, - это вложить внутрь функции сложения и вычитания.

var aPlusAbsB = function(a, b) {
    return (function(a, b) { b > 0 ? a + b : a - b })(a, b);
}

Не совсем то же самое, но он выполняет свою работу достаточно косвенным образом.

0
ответ дан 6 December 2019 в 15:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: