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.
>>
>>

Reply via email to