2010-03-09 8 views
7

Hier ist ein Lisp-Verfahren, das einfach ‚a‘ auf den absoluten Wert von ‚b‘ fügt hinzu:Erste Referenz auf das Objekt JavaScript-Funktion hinter einem Operator

(define (a-plus-abs-b a b) 
    ((if (> b 0) + -) a b)) 

Ich denke, das ist schön, und ich versuche, um die beste Möglichkeit zu finden, dies in JavaScript zu schreiben. Aber mein JavaScript-Code ist nicht schön:

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); 
} 

Das Hauptproblem ist, dass ich nicht die + und - Symbole als Hinweise auf die Funktionen verwenden, können sie wirklich darstellen, wie ich kann mit Lisp. Kann jemand eine etwas elegantere Art, etwas zu tun, oder habe ich eine Sprachgrenze erreicht?

Natürlich, ich kann dies tun:

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

, aber das ist eher ein Gedankenexperiment als eine pragmatische Frage.

Gibt es eine Möglichkeit, einen Verweis auf die Kernfunktionen in der JavaScript-Sprache zu erhalten, als ob sie benutzerdefiniert wären?

+0

Haben Sie sich Functional.js und seine skurril-süße Syntax für die Darstellung einfacher Funktionen als Strings angesehen? – Pointy

+0

Auch ich habe keine Ahnung, ob es tatsächlich Funktionsinstanzen für die eingebauten arithmetischen Operatoren gibt. – Pointy

+0

Ich habe die Funktionale Bibliothek gesehen, und sie sieht cool aus. Ich frage mich nur, ob es einen Weg gibt, dies nur mit Core JS zu tun. Und @ Pointy Ich frage mich das Gleiche. Sie sind möglicherweise keine Function-Objekte, aber dort gibt es eine Logik, die ähnlich wie eine Funktion ausgeführt wird. –

Antwort

5

Es ist eine sehr coole Idee - wäre gut für die Bewertung mathematischer Ausdrücke, aber Sie können einfach nicht einen Operator (oder die Logik dahinter) auf eine Variable setzen. Leider :-)

+0

Ich hasse es, Ihnen ein +1 für die OP Willen, aber es ist wahr, Du kannst wenig dagegen tun. –

+0

@musicfreak: lol danke ;-) Ich habe oft darüber nachgedacht, weil es Zeiten gab, in denen ich den Zustand einer Variablen überprüfen musste, um zu entscheiden, ob zu '+' oder '-', aber es wäre so viel gewesen cooler, wenn ich stattdessen einfach die '+' oder '-' übergeben hätte - es hätte eine ganze' if' Aussage gespeichert! –

+0

Wenn nicht anders durch irgendeinen herumlaufenden JavaScript-Maven bewiesen, scheint dies die Antwort :(. –

0

Dies ist etwas schöner als Ihr Vorschlag, wenn auch bei weitem nicht so schön wie Ihre Lisp Darstellung des Konzepts:

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); 
} 

Dies würde die folgend in Schema entsprechen:

(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)))))) 
3

Obwohl nicht so elegant wie der LISP-Code, könnten Sie dynamisch eine Funktion erstellen, die sich wie ein Operator (für Zahlen) verhält, aber nicht.

function op(o) { 
    return new Function("a", "b", "return a " + o + " b"); 
} 


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

Darüber hinaus können wir die Komplexität der Erzeugung diese innerhalb einer if-Wrapper verstecken, aber das ist in der Nähe Ich kann :)

function is(expr, op1, op2) { 
    return expr ? op(op1) : op(op2); 
} 

function aPlusAbsB(a, b) { 
    return (is(b > 0, '+', '-')(a, b)); 
} 
1

bekommen Ich denke, alle anderen hier zuerst bekommen, aber JS ist etwas weniger rein funktional als Lisp, Operatoren sind keine Funktionen oder Objekte, sondern Operatoren.

5

Es hängt davon ab, welche Aspekte der Lisp-Implementierung Sie besonders schön finden. Ich werde eine andere Version Ihres Vorschlags vorschlagen, die meiner Meinung nach der Syntax Ihrer Lisp-Definition etwas näher kommt, indem Sie ein paar schmutzige Dinge tun.

// 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)) 
0

Ja, das ist nicht streng möglich, die nächste Sache, die Sie tun können, ist Nest Addition und Subtraktion Funktionen innerhalb.

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

Nicht genau das gleiche, aber es wird die Arbeit in einer ausreichend indirekten Weise erledigt.

Verwandte Themen