Open lassik opened 4 years ago
Some procedures such as random-integer
are in the empty namespace, which I just learned is different from the ##
namespace. Can you access things in the empty namespace from within a define-library
form?
One way is to use an explicit namespace declaration in your code, for example:
(define-library (foobar)
(export stuff)
(import (scheme base))
(begin
(##namespace ("" pp)) ;; map pp to empty namespace
(define (stuff x)
(pp x))))
Nice. That doesn't seem to affect re-exports, however.
These don't currently work:
(define-library (srfi 27)
(export random-integer)
(begin (##namespace ("" random-integer))))
(define-library (srfi 27)
(import (only (scheme base) define))
(export random-integer)
(begin (##namespace ("" random-integer))
(define random-integer random-integer)))
(define-library (srfi 27)
(import (only (scheme base) define let))
(export random-integer)
(begin (define random-integer
((lambda ()
(namespace ("" random-integer))
random-integer)))))
These explicit ##namespace
declarations are purely local to the code implementing the body (as they should be since they are at a lower level than the module system).
Actually this was my mistake:
(define-library (srfi 27)
(import (only (scheme base) define let))
(export random-integer)
(begin (define random-integer
((lambda ()
(namespace ("" random-integer))
random-integer)))))
This works fine:
(define-library (srfi 27)
(import (only (scheme base) define lambda))
(export random-integer)
(begin (define random-integer
((lambda ()
(##namespace ("" random-integer))
random-integer)))))
I can do the wrappers using this technique.
OK... BTW it is shorter to do (let () (##namespace ("")) random-integer)
.
$ gsi gambit/libs/
Gambit v4.9.3
> (define original random-integer)
> (eq? original random-integer)
#t
> (import (srfi 27))
> (apropos "random-integer")
"srfi/27#" namespace:
random-integer
empty namespace:
random-integer
> srfi/27#random-integer
#<procedure #2 random-integer>
> (eq? srfi/27#random-integer random-integer)
#t
> (eq? srfi/27#random-integer original)
#t
OK... BTW it is shorter to do
(let () (##namespace ("")) random-integer)
.
You're right. I didn't realize Gambit supports a let
without variables.
Seems let
with no variables is standardized in R7RS. The body must still have at least one expression.
The shim approach will work for now, but with reexportation it will be possible to eliminate the srfi/27#random-integer
variable and to allow the compiler to do more optimizations (not specifically with random-integer
but for primitives that are inlined/constant-folded/etc such as bitwise-and
).
I'm currently working on implementing reexportation...
Great! How difficult is it to implement? If it's just a few days, I'll wait until it's done before doing the SRFI wrappers.
BTW, you might be interested in knowing that in the external representation for procedures #<procedure #N name-of-procedure>
the name of the procedure comes from looking up the value in the global environment (to determine the name of the global variable that contains that procedure). Here's an example:
> (define original random-integer)
> original
#<procedure #2 random-integer>
> (set! random-integer 42)
> original
#<procedure #2 original>
The reexportation feature should be available later today.
Makes sense. In a similar vein, Emacs has an apropos-value
command that looks for a particular Lisp value in all global variables and lets you search for e.g. a string that you know is stashed somewhere. Pretty wild.
Once again, thank you for your impressive dedication in taking care of Gambit.
https://srfi.schemers.org/srfi-27/srfi-27.html
According to Gambit's manual, this is already built-in. We just need to add a
(srfi 27)
library wrapper.