2009-07-22 11 views

Antwort

2

Sie definieren verschiedene Arten von Objekten (Funktionen, spezielle Variablen, Makros, Strukturen, Klassen, generische Funktionen, Methoden, Pakete). In Common Lisp befinden sie sich ebenfalls in verschiedenen Namespaces. Unterschiedliche Definition Formen auch unterschiedliche Syntax (Schema der define kombiniert Variable und Funktionsdefinition. Aber kann es eine Klasse definieren?)

+3

Schema hat keine Klassen. Und 'definieren' definiert nur wirklich Variablen - 'Lambda' definiert Funktionen. (define (a b c) ...) ist äquivalent zu (definiere a (lambda (b c) ...)) –

+2

In Schema definiert 'lambda' * nicht * eine Funktion, sondern nur eine. 'define' wird für * all * -Definitionen verwendet. Und ja, "Scheme" hat keine Klassen, aber in praktisch allen Scheme-Klassensystemen (und fast alle Implementierungen haben ein OO-System) wird "define" auch verwendet, um Klassen zu definieren, es passiert einfach, dass der Ausdruck, der in der verwendet wird Definition wird zu einer Klasse ausgewertet. –

15

defn, defmacro, defstruct und so sind nur Makros für ihre entsprechende Struktur zu definieren, was es unnötig macht vorformulierten zu schreiben Code. Zum Beispiel defn macht es einfache Funktionen zu schreiben, da Sie nicht mehr über das Setzen des Lambda-Begriff kümmern (die Sie in Schema tun können, nur durch die Argumente unmittelbar nach dem Namen definiert Bracketing wird):

Scheme:

(define hello 
    (lambda (name) 
    (display (string-append "hello, " name)))) 


(define (hello name) 
    (display (string-append "hello, " name))) 

Clojure:

(def hello 
    (fn [name] 
    (println (str "hello, " name)))) 

(defn hello [name] 
    (println (str "hello, " name))) 

Sie bei defn als mnemomic Gerät für def + fn aussehen kann. Solche Shortcuts sorgen für weniger Code-Kodierung und machen den Code im Allgemeinen einfacher lesbar. Ich lehre jemandem, wie man Scheme im Moment programmiert, und ich lasse sie die langen Formulare so verwenden, dass sie immer daran denken, was die Sprache macht (und die arbeitsparenden Makros umso mehr schätzen werden, wenn sie endlich beginnen benutze sie).

Die Formulare define oder def geben einigen nachfolgenden Ausdrücken einen Namen. Das Formular lambda oder fn gibt dem Namen einen Satz von Bindungen, wenn er in einem Ausdruck oder def verwendet wird. Das ist der Punkt, an dem die Dinge komplexer werden und die Verwendung von Makro-Formularen hält Sie gesund und schützt vor Langeweile.

+1

Ihr Schema ist dort falsch - sowohl der Funktionsname als auch das Argument sollten in Klammern gesetzt sein. Außerdem ist deine Erklärung nur ein kleiner Teil des Gesamtbildes.Die "gezuckerte" Version der Definitionen von Scheme ist * nicht *, nur um Code zu vermeiden - es ist einfacher zu benutzen (besonders für Neulinge), da das Ding, das * definiert ist, aussieht wie * es benutzt. Mit anderen Worten, Sie definieren etwas, das wie eine symbolische Vorlage für spätere Verwendungen der Funktion aussieht. –

+0

Sie haben Recht. Versuche, zu viele verschiedene Lispeln gleichzeitig im Kopf zu behalten. Scheme ist das ein oder andere Lispeln über dieses besondere Stückchen Zucker, und da ich Schema nicht viel benutzt habe und die gezuckerte Form vermieden habe, habe ich es blies. Korrigiert. – Pinochle

+1

Ich hatte nicht den kleinen kognitiven 'Priming-Trick' bemerkt, der von der gezuckerten Form gespielt wird, die die zukünftige Verwendung der Funktion in einem s-Ausdruck vorschneidet, ordentlich. Ich hatte das nicht bemerkt, zumindest nicht bewusst. Etwas störte mich immer an dieser Form, und jetzt weiß ich, was es ist. Der Grundierungstrick hängt davon ab, dass das Gehirn die Syntax von 'define' versteht, etwas mit einem s-Ausdruck zu tun zu haben, anstatt einem Namen (einem Atom) einen Wert zu geben. Ich nehme an, dass die unbewusst wahrgenommene "semantische Ungenauigkeit" mich beunruhigt hatte. – Pinochle

1

def in Clojure ist eine spezielle Form und es ist schön, spezielle Formen so einfach und primitiv wie möglich zu halten. defn ist ein Makro, das Zucker hinzufügt, um einfach Docstrings und Metadaten zu setzen, und (wie andere bereits gesagt haben) überflüssige Parens überflüssig macht. defn erstellt auch automatisch einige Metadaten für Ihre Funktion selbst (mit Arglisten usw.), die für einen allgemeinen def keinen Sinn ergeben.

Funktionen sind bei weitem die üblichste Sache, die Sie in Clojure definieren werden. Es wird davon abgeraten, veränderbare Toplevel-Variablen zu verwenden. Es macht also Sinn, eine einfache und schnelle Möglichkeit zu haben, eine Toplevel-Funktion zu definieren. Die Verwendung von def für alles würde zu einer großen Anzahl von Vorsätzen führen. Wenn es kein defn gäbe, würden wir es alle selbst neu erfinden, um nicht zu Tode genervt zu sein.

+0

"defn ist ein Makro, das leicht Zucker hinzufügt Einstellung von Docstrings und Metadaten ": Aber selbst Variablen könnten von solchen Features profitieren. Dieses Argument wäre nur gültig, wenn das Argument defn würde als def. verhalten." def für alles würde zu einer Menge Boilerplate führen. ": Könnten Sie bitte näher ausführen auf seinem dies folgt? Scheme-Code, wie Eli darauf hingewiesen hat, verwenden Sie definieren, um Variablen, Funktionen und Klassen zu benennen ... ohne irgendeine Boilerplate. – kanak

Verwandte Themen