ele...: I did not know about this sys.modules thing. Good to know.
Josh & ele...:
Agreed. I don't think pollution happens until the "using modX" call
happens. So, I don't really understand why we can't have scope-level
"using" commands.
And yes, maybe Julia *should* use a different keyword than "using" when
applied to arbitrary scopes (as opposed to when we use it at the
module-level).
...So linking back to Patrick's comment:
The "export" list sort of tells the module user what functions are meant to
be used. It just happens that Julia's implementation of "using" pulls in
all "export"-ed elements into the current module namespace. This works
extremely well with the multi-dispatch engine.
However, I can also see a place for a slightly weaker directive: Let's call
it "provide" for now. The "provide" directive could be used to tell the
user what other elements (like constructors) are "supported" by the
module. The "provide"-ed elements would not be pulled in by the "using"
statement. Only "export"-ed values do that. Instead, "provide"-ed
elements would *only* be pulled-in when a user calls "using >>namespace<<
modX" (or some other keyword).
This would allow developers to use shorter names. Names that would
otherwise collide if they were to be "export"-ed:
module Electroncis
type Circuit
name::String
elemlist::Array{CktElem}
...
end
abstract IndepCktElem
abstract drivePattern
type Vsrc <: IndepCktElem ...; end
type SineWave <: drivePattern ...; end
connect(c::Circuit, x::CktElem, n::NodeList) = ...
drive(c::Circuit, x::IndepCktElem, n::NodeList, p::drivePattern) = ...
...
export connect, drive #No problem: Can be handled by multi-dispatch
provide Circuit #Dangerous: Cannot always be resolved by
multi-dispatch
provide Vsrc, SineWave #Also a little dangerous
end
Now, in the user's module, you can do the following:
using Electronics #Brings in connect & drive, as usual
#Eventually gets a little verbose when dealing with elements that cannot
easily
#be resolved by multi-dispatch ("provide"-ed elements):
function make_circuit()
c = Electronics.Circuit("Myckt")
drive(c, Electronics.Vsrc(), [:SUPPLY, :GND], Electronics.SineWave(1e9))
return c
end
#But this function *could* be made more succinct:
function make_circuit2()
using namespace Electronics #Also brings in all other "legitimate"
elements
c = Circuit("Myckt") #More succinct constructor call
#Things gets even nicer with more complex expressions:
drive(c, Vsrc(), [:SUPPLY, :GND], SineWave(1e9))
return c
end
On Friday, March 6, 2015 at 6:36:44 PM UTC-5, [email protected] wrote:
>
> This is essentially the method used by Python (as I believe I understand
> it, import is the worst documented thing in Python). Python puts a
> reference to all modules into sys.modules, no matter where they are
> imported. And sys.modules is always the first thing searched before path.
> So all modules are imported and initialized once (excepting users
> explicitly deleteing or reloading). An no matter where the imports happen
> the first will actually load and initialize the module and all the others
> will just use that copy. But since modules are referenced by sys.modules,
> not the top level namespace, there is no pollution until a user explicitly
> imports into that namespace.
>
> On Saturday, March 7, 2015 at 5:48:11 AM UTC+10, Josh Langsfeld wrote:
>>
>> So then your results would indicate that putting 'using MyModule' inside
>> a function *could* actually bring the exported names into only the local
>> scope *if* the module had already been constructed in the global scope.
>> I know I've seen some people discuss name pollution by 'using' too many
>> modules. It might be part of a wider solution to enable local scope
>> 'using', either with a new keyword or just having 'using' check if the
>> module already exists.
>>
>>