Lone namespace extensions not visible through renamed import of original namespace
module A ~lang rhombus:
export namespace Foo
module B ~lang rhombus:
import parent!A open
export def Foo.bar = 42
import:
self!A open: rename Foo as Baz
self!B open
println(Baz.bar) // "bar: identifier not provided by Baz"
Perhaps this would fall under "limitation" as opposed to "bug"; I don't have a strong enough understanding of the implementation of namespaces to know at the moment. But at least with how I would reason about namespaces conceptually, I would expect in-scope extensions to be visible regardless of the name of the namespace itself.
As an additional data point (or a workaround), re-exporting Foo from B, and renaming it when importing from B in addition to A, seems to work:
#lang rhombus
module A ~lang rhombus:
export namespace Foo:
export def one = 1
module B ~lang rhombus:
import parent!A open
export Foo
def Foo.two = 2
import:
self!A open: rename Foo as Baz
self!B open: rename Foo as Baz
println(Baz.one)
println(Baz.two)
Curiosity's sake: what if you rename two different exported namespaces into the same name on import? Set union? Intersection? Error (preferable)?
I think the part that has gone wrong here is export def Foo.bar = 42. The intent was to never allow Foo.bar to be exported as a part of Foo independently from Foo. (An export Foo.bar by itself would correspond toexport Foo.bar as bar, exporting only bar and not Foo and not bar as part of Foo.)
As @benknoble hints, exporting export def Foo.bar = 42 goes wrong if Foo is not the right Foo in the context where the weird export is imported:
module A ~lang rhombus:
export namespace Foo
module B ~lang rhombus:
import parent!A open
export def Foo.bar = 42
module C ~lang rhombus:
export namespace Foo
import:
self!C open
self!B open
println(Foo.bar) // wrong `Foo` allows acces to `Foo.bar`
I think probably export def Foo.bar = 42 should be error. Do you need that to instead work for some context, @distractedlambda?
To finish answering @benknoble 's question, it's an error to import different namespaces with the same name:
#lang rhombus
module A ~lang rhombus:
export namespace Foo
module C ~lang rhombus:
export namespace Foo
import:
self!A open
self!C open // error
I think probably export def Foo.bar = 42 should be error. Do you need that to instead work for some context, @distractedlambda?
I didn't properly clock that it was a mis-feature, and it seemed to generally do what I expected, so I ran with it (though looking back through Discord chat history, I think you pretty clearly indicated that it wasn't intended functionality; oops).
The main thing I'm actually trying to do is split the implementation of a large-ish namespace amongst multiple files. I think I initially tried a re-export approach, but found that cumbersome or not-straightforward for reasons that I can't entirely remember. Namespace extensions seemed like a natural tool for the job, which is a large part of why I ended up stressing that mechanism so hard :)
I think I initially did the export def Foo.bar thing by mistake when refactoring some code to use the then-new export shorthand. Then, realizing it seemed to work, it also seemed convenient, since I was already making heavy use of export def and export fun elsewhere, and it freed me from having to remember to separately re-export namespaces that I extended in any given file. For whatever reason, "exporting an extension" also made more intuitive sense in my head than "exporting an extended version of an existing namespace", possibly because that's closer to how extensions work in e.g. Kotlin (which I've used in the past). But I have a very incomplete understanding of the nitty-gritty semantics of Rhombus namespaces (I've mostly just been trying things and seeing how long they do what I hope), so if it doesn't work within that framework, then it doesn't work.
Also, if export def Foo.bar and the like were to become errors... how would this interact with a definition macro that expands to such a form (but possibly others)? Like, as a contrived example:
#lang rhombus/and_meta
export namespace Foo
defn.macro 'def_many: $defns':
defns
export def_many:
def Foo.bar = 42
def baz = 17
Would the entire export def_many form be an error because one of the introduced sub-definitions is a namespace extension? Or would the namespace extension just be ignored (with baz still becoming exported)?
My experiment so far has been to make export def Foo.bar .... like def Foo.bar .... with export Foo.bar, which exports the binding as bar (and does not export Foo). In that case, export def_many would exports bar and baz.