[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Namespace confusion/pollution in languages implemented via Guile's compi
From: |
holger . peters |
Subject: |
Namespace confusion/pollution in languages implemented via Guile's compile-tower |
Date: |
Sat, 07 Nov 2020 12:54:56 +0100 |
User-agent: |
Posteo Webmail |
First of all let me begin by saying I am not quite sure whether this
is a `works as intended' or whether this constitutes a bug, I tend to
think its the latter, but wouldn't right away rule out the former, as
if it were to be considered a `bug' it probably would have surfaced
long before, but I disgress. let's get to my problem.
* Problem statement
I implemented my own language using the guile compile-tower. For the
sake of you not having to read through all of my code I provide a
snippet for reproducing the test case. But first, let's start by looking
at
the fact what I describe is present in the ecmascript iplementation
bundled with guile.
If you run Guile's ECMAscript REPL using `guile
--language=ecmascript`, something like this works:
write("test");
display(3);
newline();
Haven't looked into the ECMAscript standard but I don't think Scheme's
`write', `display' and `newline' are whats being demonstrated there.
* Reproducing Example
This creates a lang `fakescheme', that is actually identical to
`(language scheme spec)' for all items except, that there are far
fewer builtins (just `print' instead of `write').
(define-module (language fakescheme spec)
#:use-module (system base compile)
#:use-module (system base language)
#:use-module (language scheme compile-tree-il)
#:use-module (language scheme decompile-tree-il)
#:export (fakescheme))
(define (make-fresh-module)
(let ((m (make-module)))
(module-define! m 'current-reader (make-fluid))
(module-set! m 'format simple-format)
(module-define! m 'newline newline)
(module-define! m 'print write)
(module-define! m 'current-module current-module)
m))
(define-language fakescheme
#:title "fakescheme"
#:reader (lambda (port env)
((or (and=> (and=> (module-variable env
'current-reader)
variable-ref)
fluid-ref)
read)
port))
#:compilers `((tree-il . ,compile-tree-il))
#:decompilers `((tree-il . ,decompile-tree-il))
#:evaluator (lambda (x module) (primitive-eval x))
#:printer write
#:make-default-environment make-fresh-module)
The general observation is: If I run a some script using this language
using `guile --language=fakescheme -s myscript.scm', it works as
expected, i.e. the following works
(print "foo") ; works in script
(write "foo") ; fails in script
However, if I run the same code from within a repl via `guile
--language=fakescheme',
(print "foo") ; fails in repl
(write "foo") ; works in repl
* Whats going on here?
It seems that in the REPL, Guile injects the `guile-user' module
directly whereas when called with `-s` and a script guile uses the
module provided with `#:make-default-environment'. That seems strange
because overall I would expect REPL environments and non-REPL
environments to be roughly the same.
So, is this a bug? Works as intended? And if this is intended in this
way is there a workaround to make REPL and script exeution to behave
the same (preferably without namespace `pollution').
- Namespace confusion/pollution in languages implemented via Guile's compile-tower,
holger . peters <=