>> As the practise shows, although guile documentation says something >> different. In section 3.1.4.7 (A Shared Persistent Variable) >> >> "An important detail here is that the `get-balance' and `deposit' >> variables must be set up by `define'ing them at top level and then >> `set!'ing their values inside the `let' body. Using `define' within >> the `let' body would not work: this would create variable bindings >> within the local `let' environment that would not be accessible at top >> level." >> >> So one might conclude that it _is_ possible to use define inside >> a 'let' form. > > Which would be correct! For example: > > (let ((a 1)) > (define b 2) > (+ a b)) > => > 3 > > Whereas: > > (let ((a 1)) > (display a) > (newline) > (define b 2) > (+ a b)) > => > ERROR: Bad define placement > > The "special rules" are just that any defines have to come before > anything else in the body of the let.
Yeah, guess you're right (under certain circumstances :P) > I don't know exactly how it works out that using a define in > local-eval falls foul of the define placement rule, but it is not hard > to imagine that it could do. The other question is: is it really necessary to impose such limitations on "define". Why is it required to make its position inside let privileged? >> Yes, since there's local-eval and the-environment, everything I've >> ever dreamed of is possible :) >> But as I've concluded from the discourse, neither of these is >> defined in R5RS (and it makes me wonder) > > Well I've never thought this through before, but perhaps that is > because in many cases it is equivalent to create a lambda at the point > where you would call the-environment, containing the code that you > would later pass to local-eval. > > For example, the ++ example then becomes: > > (define ++ (let ((c 0)) (lambda () (begin (set! c (+ c 1)) c)))) > > - which is the traditional way of writing this example. You didn't focus :> The whole idea of accessing a closure environment was in fact to make scheme object oriented programming more intuitive. In guile info pages there's an oo closure example: (section 3.1.4.9 "Example 4: Object Orientation") " (define (make-account) (let ((balance 0)) (define (get-balance) balance) (define (deposit amount) (set! balance (+ balance amount)) balance) (define (withdraw amount) (deposit (- amount))) (lambda args (apply (case (car args) ((get-balance) get-balance) ((deposit) deposit) ((withdraw) withdraw) (else (error "Invalid method!"))) (cdr args))))) (define my-account (make-account)) " Notice the ugly "case" statement that requires the variables to be accessed in the following manner (the same example, a few lines later): " (my-account 'get-balance) => 0 (my-account 'withdraw 5) => -5 (my-account 'deposit 396) => 391 (my-account 'get-balance) => 391 " This is ugly as it requires doubling the names of functions. Perhaps it could be overcome with some sort of macro, but the "with" I proposed allows to avoid the whole "case" and to write (after slight modifications in the "let" form): (with my-account (get-balance)) Or maybe I think wrong; I'm new in the world of lisp, so please forgive me my mistakes :) Best regards, M