Hi Jens,

Thank you for telling me that Racket does not support capture and extend
environments.

So that I can change direction.

Hi all,

I found that Guile has a function called `local-eval`, which can be used to
simulate FEXPRs.

see
https://www.gnu.org/software/guile/manual/guile.html#index-local_002deval

I implemented do-notation by `local-eval`.

```
;guile 2.2.3
(use-modules (ice-9 local-eval))
(use-modules (ice-9 match))
(use-modules (srfi srfi-9))

(define-record-type Just
  (make-Just x)
  Just?
  (x Just-x))

 (define-record-type Nothing
  (make-Nothing)
  Nothing?)

(define (extends-env env var-name value)
  (local-eval
   `(let ((,var-name ,value))
      (the-environment)) env))

(define (do env binds return)
  (match binds
    [()
     (begin
       (local-eval return env))]
    [((var e) rest-binds ...)
     (begin
       (match (local-eval e env)
         [($ Nothing) (make-Nothing)]
         [($ Just x) (do (extends-env env var x) rest-binds return)])
       )]))

(define (bigger-than-two n)
  (if (> n 2)
      (make-Just n)
      (make-Nothing)))

(display
 (do (the-environment)
        (list '[x (bigger-than-two 4)]
              '[y (bigger-than-two 5)])
        '(make-Just (+ x y))))
```

I was surprised that it works.

PS: The code above can be compiled and run in guile 2.2.3.
You can test it at https://rextester.com/l/scheme_online_compiler, if
someone interested,

Best regards,
Siyuan Chen


On Mon, Jun 8, 2020 at 12:23 AM Jens Axel Søgaard <[email protected]>
wrote:

> Den søn. 7. jun. 2020 kl. 14.09 skrev Siyuan Chen <[email protected]>:
>
> Unfortunately, this code doesn't work, because it lacks two functions,
>> `get-current-env` and `extends-env`.
>>
>
> These are not available since static lexical scope makes it possible for
> the compiler to determine where
> a variable is stored at compile time. Therefore an explicit environment is
> not needed.
> (See "early binding" vs "late binding").
>
>
>> Is there any way to work around this issue?
>>
>
>
>> I have searched Racket's document. Racket has namespaces that are very
>> similar to the environment here.
>>
>> But it seems that `current-namespace` can not get binding (e.g. Just) and
>> `namespace-set-variable-value!` is a mutable function which is not suitable
>> as well.
>>
>
> Namespaces are "environment-like" but contain only top-level variables.
>
> Could someone give me some advice?
>> Or we can modify the code above to make it work in Racket.
>>
>
> Since this for educational/fun use and not practical, I suggest using a
> Scheme interpreter where the environments
> are explicit.  Then you can easily add `get-current-env` and `extends-env`
> yourself.
>
> One option is the interpreter page LiSP (Lisp in Small Pieces) where an
> interpreter for fexprs is discussed
> with full working code.
>
> /Jens Axel
> https://racket-stories.com
>
>
>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAHWTsYkD7i2ctsc-rAYrjjKBNKBBd8rQvqni2%2B-F%3DHV8PHtWiw%40mail.gmail.com.

Reply via email to