# Calling into a Chez Scheme library from Racket -- imported symbol rewritten in vm-eval?

**URL:** <https://racket.discourse.group/t/calling-into-a-chez-scheme-library-from-racket-imported-symbol-rewritten-in-vm-eval/2257>\
**Category:** Questions & Answers\
**Tags:** question, ffi, chez\
**Created:** [August 28, 2023, 11:19pm UTC](https://racket.discourse.group/t/calling-into-a-chez-scheme-library-from-racket-imported-symbol-rewritten-in-vm-eval/2257 "2023-08-28T23:19:33Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![awwx](https://avatars.discourse-cdn.com/v4/letter/a/13edae/32.png) [@awwx](https://racket.discourse.group/u/awwx)\
**Post date:** [August 28, 2023, 11:19pm UTC](https://racket.discourse.group/t/calling-into-a-chez-scheme-library-from-racket-imported-symbol-rewritten-in-vm-eval/2257/1 "2023-08-28T23:19:33Z")

</div>

I have a Chez Scheme library "foo.ss" that I'd like to call from Racket:

```scheme
(library (foo)
   (export bar)
   (import (rnrs))

   (define (bar) "hello"))

```

From Chez Scheme:

```scheme
$ chezscheme
Chez Scheme Version 9.5.4
Copyright 1984-2020 Cisco Systems, Inc.
> (eval '((lambda () (import (foo)) (bar))))
"hello"

```

And my Racket program "call.rkt" which attempts to use the library:

```scheme
#lang racket

(require ffi/unsafe/vm)

(vm-eval
 '((lambda () (import (foo)) (bar))))

```

```scheme
$ racket call.rkt
variable bar554 is not bound
  context...:
   body of "/home/andrew/prj/audit/compile/call.rkt"

```

What would be the right way to do this?

Thank you!

Andrew

---

<div class="post-metadata">

**Author:** ![LiberalArtist](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/liberalartist/32/151_2.png) [@LiberalArtist](https://racket.discourse.group/u/LiberalArtist)\
**Post date:** [August 29, 2023, 1:55pm UTC](https://racket.discourse.group/t/calling-into-a-chez-scheme-library-from-racket-imported-symbol-rewritten-in-vm-eval/2257/2 "2023-08-29T13:55:24Z")

</div>

I don't know the solution, but I think at least part of the problem would be that Racket CS does not consult the default Chez Scheme search path for Scheme libraries, because it does not expect to use any Scheme libraries other than those in its bootfiles.

---

<div class="post-metadata">

**Author:** ![awwx](https://avatars.discourse-cdn.com/v4/letter/a/13edae/32.png) [@awwx](https://racket.discourse.group/u/awwx)\
**Post date:** [August 30, 2023, 1:28am UTC](https://racket.discourse.group/t/calling-into-a-chez-scheme-library-from-racket-imported-symbol-rewritten-in-vm-eval/2257/3 "2023-08-30T01:28:48Z")

</div>

> [@LiberalArtist](#):
>
> Racket CS does not consult the default Chez Scheme search path for Scheme libraries

The code isn't using Racket to load the Chez library... the default Chez Scheme library path is the current directory, and this doesn't appear to have been changed in the VM environment:

```scheme
$ racket
Welcome to Racket v8.10 [cs].
> (require ffi/unsafe/vm)
> (vm-eval '(library-directories))
'(("." . "."))

```

And loading the library from Chez appears to be working (at least there isn't an error):

```scheme
$ racket
Welcome to Racket v8.10 [cs].
> (require ffi/unsafe/vm)
> (vm-eval '(import (foo)))
> 

```

I imagine the Chez Scheme library import might be doing some kind of hygienic macro renaming of symbols. I don't know how to get around that.

---

<div class="post-metadata">

**Author:** ![awwx](https://avatars.discourse-cdn.com/v4/letter/a/13edae/32.png) [@awwx](https://racket.discourse.group/u/awwx)\
**Post date:** [August 30, 2023, 1:39am UTC](https://racket.discourse.group/t/calling-into-a-chez-scheme-library-from-racket-imported-symbol-rewritten-in-vm-eval/2257/4 "2023-08-30T01:39:52Z")

</div>

Interesting, it seems like it isn't some quirk of `vm-eval`, but maybe something about Chez libraries not working in the VM environment?

script.ss:

```scheme
((lambda ()
  (import (foo))
  (write (bar))
  (newline)))

```

```scheme
$ chezscheme 
Chez Scheme Version 9.5.4
Copyright 1984-2020 Cisco Systems, Inc.

> (load "script.ss")
"hello"

```

```scheme
$ racket
Welcome to Racket v8.10 [cs].
> (require ffi/unsafe/vm)
> (vm-eval '(load "script.ss"))
; variable bar585 is not bound [,bt for context]

```

---

<div class="post-metadata">

**Author:** ![shhyou](https://avatars.discourse-cdn.com/v4/letter/s/ccd318/32.png) [@shhyou](https://racket.discourse.group/u/shhyou)\
**Post date:** [August 30, 2023, 7:04pm UTC](https://racket.discourse.group/t/calling-into-a-chez-scheme-library-from-racket-imported-symbol-rewritten-in-vm-eval/2257/5 "2023-08-30T19:04:00Z")

</div>

Could be! I tried this and it manages to run, but I don't understand Scheme enough to tell what's going on:

```scheme
;; go.ss
(import (foo) (rnrs))
(write (bar))
(newline)

```

```scheme
$ racket
> (require ffi/unsafe/vm)
> (vm-eval '(load-program "go.ss"))
"hello"

```

So that `vm-eval` is wrapped inside some library? Racket's `vm-primitive` is implemented via `primitive-lookup` here, I'm not sure how this call to `eval` interacts with the environment.  
(In case it's relevant, I believe Racket's entry point is this [https://github.com/racket/racket/blob/06f10d51d11ded84df9805578245bfd80391b96a/racket/src/cs/main.sps](https://github.com/racket/racket/blob/06f10d51d11ded84df9805578245bfd80391b96a/racket/src/cs/main.sps).)

[https://github.com/racket/racket/blob/06f10d51d11ded84df9805578245bfd80391b96a/racket/src/cs/linklet.sls#L154-L163](https://github.com/racket/racket/blob/06f10d51d11ded84df9805578245bfd80391b96a/racket/src/cs/linklet.sls#L154-L163)

> ```scheme
> (library (linklet)
> (export ... primitive-lookup ...)
> (define (primitive-lookup sym)
> (unless (symbol? sym)
> (raise-argument-error 'primitive-lookup "symbol?" sym))
> (call-with-system-wind
> (lambda ()
> (guard
> (c [else #f])
> (eval sym)))))
> 
> ```

---

<div class="post-metadata">

**Author:** ![shhyou](https://avatars.discourse-cdn.com/v4/letter/s/ccd318/32.png) [@shhyou](https://racket.discourse.group/u/shhyou)\
**Post date:** [August 31, 2023, 5:26am UTC](https://racket.discourse.group/t/calling-into-a-chez-scheme-library-from-racket-imported-symbol-rewritten-in-vm-eval/2257/6 "2023-08-31T05:26:20Z")

</div>

In Racket's main program, the exposed `eval` is the one that goes through Racket's expander, not Chez Scheme's `eval`. I wonder if that has affected the result of `(vm-primitive 'eval)` and therefore affected `vm-eval`, or that some `current-eval` parameter is different so the `lambda` in your example actually went through Racket's expander.

These tests seem to suggest otherwise, though, so I don't know how to make sure to run raw Scheme expressions without going through Racket's frontend.

```plaintext
Welcome to Racket v8.10.0.3 [cs].
> (require ffi/unsafe/vm)
> (equal? (vm-eval (quote call-with-current-continuation)) (vm-eval (quote ($primitive call-with-current-continua
tion))) )
#f
> (equal? (vm-eval (quote eval)) (vm-eval (quote ($primitive eval))) )
#t

```

In particular, I don't understand why the second expression is `#t`. That suggests that the `eval` obtained by running `vm-eval` is the same one as the primitive Chez Scheme `eval`, but in `main.sps` the `eval` is shadowed by the `eval` from the expander ([https://github.com/racket/racket/blob/06f10d51d11ded84df9805578245bfd80391b96a/racket/src/cs/main.sps#L1-L27](https://github.com/racket/racket/blob/06f10d51d11ded84df9805578245bfd80391b96a/racket/src/cs/main.sps#L1-L27)).

---

<div class="post-metadata">

**Author:** ![awwx](https://avatars.discourse-cdn.com/v4/letter/a/13edae/32.png) [@awwx](https://racket.discourse.group/u/awwx)\
**Post date:** [August 31, 2023, 5:31am UTC](https://racket.discourse.group/t/calling-into-a-chez-scheme-library-from-racket-imported-symbol-rewritten-in-vm-eval/2257/7 "2023-08-31T05:31:29Z")

</div>

> [@shhyou](#):
>
> ```scheme
> (vm-eval '(load-program "go.ss"))
> 
> ```

That's promising! Now all I need is a way to get a value from the loaded program back up into Racket.

`load-program` doesn't return a value (it doesn't return the last value in go.ss), so I can't get a value that way...

The loaded program also doesn't seem to have access to "globals" defined with `vm-eval`:

```scheme
$ racket
Welcome to Racket v8.10 [cs].
> (require ffi/unsafe/vm)
> (vm-eval '(define abc 123))
> (vm-eval 'abc)
123
> (vm-eval '(load-program "go.ss"))
; attempt to reference unbound identifier abc [,bt for context]

```

where `go.ss` is:

```scheme
(import (foo) (rnrs))
(write abc)
(newline)

```

🤔

---

<div class="post-metadata">

**Author:** ![shhyou](https://avatars.discourse-cdn.com/v4/letter/s/ccd318/32.png) [@shhyou](https://racket.discourse.group/u/shhyou)\
**Post date:** [August 31, 2023, 6:00am UTC](https://racket.discourse.group/t/calling-into-a-chez-scheme-library-from-racket-imported-symbol-rewritten-in-vm-eval/2257/8 "2023-08-31T06:00:26Z")

</div>

Okay something sketchy is going on. I don't know how this went through 😂

```plaintext
$ racket
Welcome to Racket v8.10.0.3 [cs].
> (require ffi/unsafe/vm)
> (vm-eval '(top-level-program (import (foo)) bar))
> (vm-eval '(import (foo)))
> (vm-eval 'bar)
#<procedure:bar>
> ((vm-eval 'bar))
"hello"

```

Perhaps posting the question to ＃internal on Racket discord can help.

---

<div class="post-metadata">

**Author:** ![mflatt](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/mflatt/32/6_2.png) [@mflatt](https://racket.discourse.group/u/mflatt)\
**Post date:** [August 31, 2023, 1:26pm UTC](https://racket.discourse.group/t/calling-into-a-chez-scheme-library-from-racket-imported-symbol-rewritten-in-vm-eval/2257/9 "2023-08-31T13:26:42Z")

</div>

I think the problem is how Racket adjusts `import` expansion via the `expand-omit-library-invocations` parameter. You can restore it while evaluating like this:

```scheme
#lang racket
(require ffi/unsafe/vm)

(define call-with-import-working
  (vm-eval '(lambda (thunk)
              (call-with-system-wind
               (lambda ()
                 (parameterize ([expand-omit-library-invocations #f])
                   (thunk)))))))

(call-with-import-working
 (lambda ()
   (vm-eval
    '((lambda () (import (foo)) (bar))))))

```

---

<div class="post-metadata">

**Author:** ![awwx](https://avatars.discourse-cdn.com/v4/letter/a/13edae/32.png) [@awwx](https://racket.discourse.group/u/awwx)\
**Post date:** [September 1, 2023, 2:15am UTC](https://racket.discourse.group/t/calling-into-a-chez-scheme-library-from-racket-imported-symbol-rewritten-in-vm-eval/2257/10 "2023-09-01T02:15:31Z")

</div>

Success!

`call.rkt`:

```scheme
#lang racket

(require ffi/unsafe/vm)

(define call-with-import-working
  (vm-eval '(lambda (thunk)
              (call-with-system-wind
               (lambda ()
                 (parameterize ([expand-omit-library-invocations #f])
                   (thunk)))))))

(define bar
  (call-with-import-working
   (lambda ()
     (vm-eval
      '((lambda () (import (foo)) bar))))))

(printf "bar: ~s~n" (bar))

```

```scheme
$ racket call.rkt
bar: "hello"

```

Thanks @mflatt!
