2010-09-14 11 views
4

Je suis très nouveau à lisp et récemment j'ai découvert le mince que je ne comprends pas.Petite question sur le régime

Ce code fonctionne:

(define (f x) (define a x) (define (b) a) (b)) 

Et cela ne:

(define (f x) (define a x) (define b a) b) 

Pourquoi?

+0

Cela fonctionne. Votre système signale-t-il une erreur? –

+0

Quelqu'un peut-il reformuler une question? – pramodc84

Répondre

2

Dans kawa interpeter cela fonctionne En Guile il n'a pas, parce que ce code

(define (f x) (define a x) (define b a) b) 

est ÉTENDU pour

(define (f x) (letrec ((a x) (b a)) b)) 

Et vous ne pouvez pas accéder à a avant assignons. letrec ne fonctionnera pas pour les définitions non-fonction, par exemple:

(letrec ((x 5) 
     (y x)) 
    y) 

Vous pouvez utiliser let* insted

(define (f x) (let* ((a x) (b a)) b)) 

Dans ce code

(define (f x) (define a x) (define (b) a) (b)) 

Dans la procédure b vous accédez à un varible quand c'est déjà défini.

+0

Deux problèmes dans cette question: * Certaines versions de 'letrec's ne fonctionneront pas, pas toutes (en particulier, celles qui l'implémentent comme' letrec * '). En outre, ceux qui implémentent un 'letrec' plus strict ne permettent pas d'utiliser un nom lié dans l'une des (autres) expressions - il n'y a pas d'implémentation Scheme qui les limite uniquement aux fonctions. (OTOH, ML fait.) –

2

Vous devriez rechercher des discussions à propos de letrec* - certaines implémentations l'utilisent comme une version plus permissive du letrec plus stricte, ce qui entraîne la différence que vous voyez.

0

Vous pouvez observer le changement de comportement entre les normes R5RS et R6RS. L'une des changes in R6RS est "Les définitions internes sont maintenant définies en termes de letrec*".

En R5RS, le define s are completely equivalent interne à un letrec. En particulier, la section sur les définitions internes dit que "de même que pour l'expression letrec équivalente, il doit être possible d'évaluer chaque <expression> de chaque définition interne dans un <body> sans affecter ou se référer à la valeur de <variable> étant défini."

Cependant, dans R6RS, interne define s are equivalent à letrec*. Et, comme vous vous en doutez, letrec*allows vous vous référez à la valeur des variables précédentes dans l'initialiseur pour les variables ultérieures.