How come Gambit enforces the module# syntax for namespaces? I have just started using them, and have looked at many posts describing the system, but I don't remember anyone explaining the reason for this syntax.
For example, trying anything different than module gives an error:
(namespace ("foo:"))
*** ERROR IN (console)@1.13 -- Ill-formed namespace prefix
I would like to use the colon syntax as I find it much more readable, especially for user-land code. I'm going to usually use fully qualified names, so this slight readability improvement is important. Is there a reason I shouldn't be able to do this?
Afficher les réponses par date
As I've said before on this list, I consider the # based namespaces good as lowlevel building blocks for your own module/namespaces handling. And for this purpose it's *good* that not the : character has been chosen. This leaves : free for your own purpose.
Two points:
- if you always fully qualify your identifyers, you don't need any system support for namspaces at all (just use R5RS identifyers happening to have colons in them).
- you usually want _short_ namespace prefixes if you're using them often in user code to prevent having long identifyers (for less typing and better readability). OTOH, you want _long_ namespace names to decrease the risk of namespace clashes between different authors. The obvious solution for this is to map globally unique namespace names onto short local namespace prefixes. And, as I've said, for this the # syntax comes in fine: you could, for example, have an identifyer being fully qualified with a globally unique namespace name (directly accessed using the lowlevel Gambit namespacing):
christianjaeger-foobar-subfu#foo
or maybe even, if you want,
org.apache.foobarproject.somemodule#foo
and then your importer aliases those to, for example,
(import christianjaeger-foobar-subfu as: subfu)
and use the foo value as
subfu:foo
(or directly as foo if no clashes occur)
or (import org.apache.foobarproject.somemodule as: fb) and use it's foo value as
fb:foo
just for the scope of the module where those import statements are being used.
How exactly this mapping and import syntax should look is open for discussion and implementation.
BTW you should maybe take a look at the "Snow!" packaging/module system.
Christian.
James Long wrote:
How come Gambit enforces the module# syntax for namespaces? I have just started using them, and have looked at many posts describing the system, but I don't remember anyone explaining the reason for this syntax.
For example, trying anything different than module gives an error:
(namespace ("foo:"))
*** ERROR IN (console)@1.13 -- Ill-formed namespace prefix
I would like to use the colon syntax as I find it much more readable, especially for user-land code. I'm going to usually use fully qualified names, so this slight readability improvement is important. Is there a reason I shouldn't be able to do this? _______________________________________________ Gambit-list mailing list Gambit-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
Here's the main the problem I'm trying to solve: I'm trying to figure out how to export records or types (or anything that uses macro rewriting). my system will use records extensively, using define-structure or define-type. Obviously I don't want to have to manually export every function that define-type creates.
I suppose there's an argument to be made that the module owning a record type should be the only thing with complete access to it, and it should delegate control by exporting getter/setter functions and constructors. However, it seems like that could get tedious.
I'm developing prototype apps just to get a feel for how I want to do things, and currently I'm trying out this pattern that binds everything to a namespace (as described in Feeley's email):
(namespace ("foo#")) (##include "~~/lib/gambit#.scm") (define-structure bar a b c)
and when referencing code outside of the current module, always use fully qualified identifiers:
(namespace ("")) (define obj (foo#make-bar 1 2 3)) (foo#bar-a bar)
I won't feel comfortable using Snow until I get a feel for how I want to structure my modules. It looks great though, and I may end up using it when I write production-ready code.
Christian, does chjmodule support what you described?
(import christianjaeger-foobar-subfu as: subfu) (subfu:foo)
If so, how does it scan the namespace?
Marc, thanks for more examples on Gambit's namespaces. I was thinking that (namespace) simply mapped all the definitions afterward (or some if given a list of identifiers) to new names with the supplied prefix. It's a little more complex though, so "#" must be hardcoded into the system.
On 7/30/07, Christian Jaeger christian@pflanze.mine.nu wrote:
- if you always fully qualify your identifyers, you don't need any
system support for namspaces at all (just use R5RS identifyers happening to have colons in them).
- you usually want _short_ namespace prefixes if you're using them often
in user code to prevent having long identifyers (for less typing and better readability). OTOH, you want _long_ namespace names to decrease the risk of namespace clashes between different authors. The obvious solution for this is to map globally unique namespace names onto short local namespace prefixes. And, as I've said, for this the # syntax comes in fine: you could, for example, have an identifyer being fully qualified with a globally unique namespace name (directly accessed using the lowlevel Gambit namespacing):
christianjaeger-foobar-subfu#foo
or maybe even, if you want,
org.apache.foobarproject.somemodule#foo
and then your importer aliases those to, for example,
(import christianjaeger-foobar-subfu as: subfu)
and use the foo value as
subfu:foo
(or directly as foo if no clashes occur)
or (import org.apache.foobarproject.somemodule as: fb) and use it's foo value as
fb:foo
just for the scope of the module where those import statements are being used.
How exactly this mapping and import syntax should look is open for discussion and implementation.
BTW you should maybe take a look at the "Snow!" packaging/module system.
Christian.
James Long wrote:
How come Gambit enforces the module# syntax for namespaces? I have just started using them, and have looked at many posts describing the system, but I don't remember anyone explaining the reason for this syntax.
For example, trying anything different than module gives an error:
(namespace ("foo:"))
*** ERROR IN (console)@1.13 -- Ill-formed namespace prefix
I would like to use the colon syntax as I find it much more readable, especially for user-land code. I'm going to usually use fully qualified names, so this slight readability improvement is important. Is there a reason I shouldn't be able to do this? _______________________________________________ Gambit-list mailing list Gambit-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
On 30-Jul-07, at 10:32 AM, James Long wrote:
Here's the main the problem I'm trying to solve: I'm trying to figure out how to export records or types (or anything that uses macro rewriting). my system will use records extensively, using define-structure or define-type. Obviously I don't want to have to manually export every function that define-type creates.
I suppose there's an argument to be made that the module owning a record type should be the only thing with complete access to it, and it should delegate control by exporting getter/setter functions and constructors. However, it seems like that could get tedious.
Just define your own define-type like macro that does what you want:
(my-define-type bar a b c)
should expand to
(##namespace ("bar#" make-bar bar? bar-a bar-a-set! bar-b bar-b-set!)) (define-type bar a b c)
If you want to experiment with different namespace separators in gsi, just compile this file:
;; File: "gambcext.scm"
(declare (block))
(define ##namespace-separators '(## #:)) (set! ##namespace-separators ##namespace-separators)
(define (##full-name? sym) ;; full name if it contains a namespace separator (let ((str (##symbol->string sym))) (let loop ((i (##fixnum.- (##string-length str) 1))) (if (##fixnum.< i 0) #f (if (##memq (##string-ref str i) ##namespace-separators) #t (loop (##fixnum.- i 1)))))))
(define (##valid-prefix? str)
;; non-null name followed by a namespace separator at end is ;; valid as is the special prefix ""
(let ((l (##string-length str))) (or (##fixnum.= l 0) (and (##not (##fixnum.< l 2)) (##memq (##string-ref str (##fixnum.- l 1)) ##namespace-separators)))))
and put it in the Gambit installation directory so that it is automatically loaded. You can change the namespace-separators at run time with a
(set! ##namespace-separators '(## #: ...))
Marc
On 30-Jul-07, at 1:42 AM, James Long wrote:
How come Gambit enforces the module# syntax for namespaces? I have just started using them, and have looked at many posts describing the system, but I don't remember anyone explaining the reason for this syntax.
For example, trying anything different than module gives an error:
(namespace ("foo:"))
*** ERROR IN (console)@1.13 -- Ill-formed namespace prefix
I would like to use the colon syntax as I find it much more readable, especially for user-land code. I'm going to usually use fully qualified names, so this slight readability improvement is important. Is there a reason I shouldn't be able to do this?
Yes. It is so that the Scheme front-end (in the compiler and interpreter) can detect that an identifier is a "fully qualified" identifier and handle them accordingly. Fully qualified identifiers must have an embedded "#", as in foo#bar or foo#bar#baz or ##car. Fully qualified identifiers bypass the effects of the namespace declaration (i.e. the namespace prefix is not automatically added).
For example, in the following program containing no namespace declaration:
(define (baz) (list hot#stuff my:stuff))
the front-end will not remap the identifiers, giving:
define -> define baz -> baz list -> list hot#stuff -> hot#stuff my:stuff -> my:stuff
If we add the namespace declaration (namespace ("foo#")), i.e.
(namespace ("foo#")) (define (baz) (list hot#stuff my:stuff))
the front-end will remap all the "non fully qualified" identifiers, giving:
define -> foo#define baz -> foo#baz list -> foo#list hot#stuff -> hot#stuff my:stuff -> foo#my:stuff
Note that because of this namespace declaration the expression (define ...) is no longer a procedure definition. To fix this we need to prevent the identifier "define" (and "list") to be remapped. We can do this several ways. Either:
(namespace ("foo#") ("" define list)) (define (baz) (list hot#stuff my:stuff))
or
(namespace ("foo#")) (##namespace ("" define list)) (define (baz) (list hot#stuff my:stuff))
or
(namespace ("foo#") ("" namespace)) (namespace ("" define list)) (define (baz) (list hot#stuff my:stuff))
or
(namespace ("foo#")) (##include "~~/lib/gambit#.scm") (define (baz) (list hot#stuff my:stuff))
Marc