Frage

I funktionale Sprachen (Emacs Lisp) Lernen endlich begonnen und es macht explizite Unterscheidung zwischen Funktionen und Sonderformen, wie Flusssteuerung, zum Beispiel, wenn.

Gibt es einen grundlegenden / theoretischen Grund, warum spezielle Formen von Funktionen unterscheiden? Sie alle Sprachen bieten funktionelle if?

Danke

War es hilfreich?

Lösung

Mit eifriger Auswertung wird die Unterscheidung erforderlich, Sprachen mit lazy evaluation (d Haskell), wenn et al. werden Funktionen können.

Eager Auswertung. Die Argumente der Funktion ausgewertet vor Aufruf der Funktion, und nur die Ergebnisse werden an die Funktion übergeben

Verzögerte Auswertung. Eine Funktion, die Argumente ausgewertet, wenn und nur dann, wenn auf sie zugegriffen wird

Andere Tipps

Wenn if eine normale Funktion war, dann beide ihre Argumente -die dann bilden und andere Form -would beide ausgewertet werden vor Aufruf der if Funktion, denn das ist die Regel Funktionsauswertung : auswerten alle Argumente Werte zu erzeugen, liefert dann diese Folge von Werten als Argumente für die Funktion, die durch das erste Symbol in der Liste bezeichnet ist.

Stattdessen mit if, was Sie wollen, ist zu tun, zu bewerten genau eine der dann bilden und andere Form , nicht beide. Um Unterdrückungs Bewertung der einen oder anderen, müssen Sie entweder ein Makro oder eine

In Sprachen wie Emacs Lisp und Common Lisp, sind spezielle Formen eingebauten Sprachkonstrukte. Sie haben unterschiedliche Bewertungsregeln, dass die normale Funktionsaufrufe. Für normale Funktionsaufrufe werden alle Argumente ausgewertet. So können Sie nicht eine IF als eine normale Funktion schreiben - die Bedingung bestimmt, welche Klausel ausgewertet wird. Auch in der Regel können Sie nicht Ihre eigenen speziellen Formen schreiben - in Common Lisp gibt es kein Sprachkonstrukt für eine spezielle Form definieren (obwohl einzelne Implementierungen der bestehenden irgendwie umgesetzt haben müssen dies führen zu Makros Mit Hilfe von Makros können Sie eine syntaktische Transformation schreiben.. dass Transformationen einen Ausdruck in eine andere. um in der Lage sein, zu schreiben, wenn als Makro, müssen Sie eine andere bedingte Form haben, die Sie für den transformierten Code verwenden können. Lisp conditionals als Basiskonstrukte zur Verfügung stellt. Nehmen wir an, COND ist so ein Grundkonstrukt , dann könnte man IF in eine Nutzung von COND erweitern.

MY-IF als Makro in Common Lisp:

(defmacro my-if (condition true-clause false-clause)
   `(cond (,condition ,true-clause)
          (t ,false-clause)))

So

(my-if (foo-p) 'one 'two)

wird expandiert in

(cond ((foo-p) 'one)
      (t 'two))

Der Vollständigkeit halber: Es gibt keine Sonderformen in der Pico Sprache zum Beispiel, und if ist ein primitiver Funktion , während Pico von Scheme inspiriert und eifrig Bewertung durch Standard hat.

In Schema könnte man schreiben

(define (true t f)
  (t))

(define (false t f)
  (f))

(define (function_if c t e)
  (c t e))

und dann

(function_if true (lambda () 'true) (lambda () 'false))
==> true

Was ist überschaubar in Pico macht, ist, dass Sie definieren können Funktionsparameter , die funktionale Argumente, die „automatisch“ verzögert sind. Dies bedeutet, dass Sie müssen die Verpackung innerhalb lambdas selbst nicht zu tun. Pico hat daher eifrig Auswertung aber mit lazy evaluation auf Nachfrage, wodurch die Notwendigkeit für spezielle Formen zu umgehen.

Also, in Schema Syntax mit funktionellen Parametern können Sie kodieren booleans wie:

(define (true (t) (f))
  (t))

(define (false (t) (f))
  (f))

Dann Funktion, wenn wird:

(define (function_if c (t) (e))
  (c (t) (e)))

und

(function_if true 'true 'false)
==> true

Als ein weiteres Beispiel die Definition der Funktion and ist (define (and p (q)) (p (q) false)).

Ebenso können Sie festlegen, or, not, while, for, ... als Funktionen, unter Verwendung der oben Codieren von booleans.

Kurze Antwort: Nr.

Long (er) Antwort: (if ...) erfordert, dass Sie die Auswertung Reihenfolge der Argumente steuern. Lisp, kann eine eifrige Sprache ist nicht dies in einer Funktion.

Umgehung: tun Sie es in einem Makro:

(defmacro _if (cnd true false)
    (let (  (gcond (gensym))
            (gresp (gensym)))
        `(let ( (,gcond ,cnd) ;`#quotes
                (,gresp nil))        
            (and ,gcond       (setf ,gresp (multiple-value-list ,true)))
            (and (not ,gcond) (setf ,gresp (multiple-value-list ,false)))
            (values-list ,gresp))))

Zum Beispiel:

[dsm@localhost:~]$ clisp -q
[1]> (defmacro _if (cnd true false)
    (let (  (gcond (gensym))
            (gresp (gensym)))
        `(let ( (,gcond ,cnd) ;`#quotes
                (,gresp nil))        
            (and ,gcond       (setf ,gresp (multiple-value-list ,true)))
            (and (not ,gcond) (setf ,gresp (multiple-value-list ,false)))
            (values-list ,gresp))))
_IF
[2]> (_if (= 1 1) (+ 2 3) "bar")
5
[3]> (_if (= 1 2) (+ 2 3) "bar")
"bar"
[4]> 

In Scala ist es möglich Modell if mit korrektem Nebeneffekt Auswertung mit Call-by-Namen Argumenten.

def If[A](cond : Boolean, truePart : => A, falsePart : => A) = if (cond) truePart else falsePart

Diese können Feature-Modell viel verwendet werden, von neue Kontrollstrukturen auch.

IF könnte eine Funktion in einer funktionalen Sprache mit Call-by-namen Semantik (lazy evaluation), wie im Lambda-Kalkül oder Algol sein. In der Tat, das ist, glaube ich, im Herzen der Beziehung zwischen Turingmaschinen und Lambda Calculus als gleichwertig Grundlagen für die Berechnung. Jedoch in Sprachen mit Nebenwirkungen (wie Zuweisungen zu Variablen) ist es nicht viel verwendet wird, da , wenn Dinge passieren, ist wichtig.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top