guile-user
[Top][All Lists]
Advanced

[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').



reply via email to

[Prev in Thread] Current Thread [Next in Thread]