A small question about the scheme

I am very new to lisp, and recently I discovered a thin one that I do not understand.

This code works:

(define (fx) (define ax) (define (b) a) (b)) 

And this is not so:

 (define (fx) (define ax) (define ba) b) 

Why?

+4
source share
3 answers

In the cava interpreter, it works. In Guile, this is not so, because this code

 (define (fx) (define ax) (define ba) b) 

expands to

 (define (fx) (letrec ((ax) (ba)) b)) 

And you cannot access a until appointment. letrec will not work for non-functional definitions, for example:

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

You can use let* insted

 (define (fx) (let* ((ax) (ba)) b)) 

In this code

 (define (fx) (define ax) (define (b) a) (b)) 

In procedure b, you access the variable if it is already defined.

+2
source

You should look for letrec* discussions - some implementations use it as a more permissive version of a more rigorous letrec , which leads to the difference you see.

+2
source

You may be seeing a change in behavior between the R5RS and R6RS standards. One of the changes in R6RS : "Internal definitions are now defined in terms of letrec* ."

In R5RS, the internal define completely equivalent to letrec . In particular, the section on internal definitions says: "As with the equivalent letrec expression, it should be possible to evaluate each <expression> each internal definition in <body> without assigning or referencing the value of any <variable> .

However, in R6RS, an internal define equivalent to letrec* . And, as you would expect, letrec* allows you to refer to the value of previous variables in the intializer for later variables.

0
source

All Articles