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 <jensa...@soegaard.net>
wrote:

> Den søn. 7. jun. 2020 kl. 14.09 skrev Siyuan Chen <chanse...@gmail.com>:
>
> 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 racket-users+unsubscr...@googlegroups.com.
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