After reading this response, I realized that maybe I don't have a complete 
grasp on how and when a module's method is overwritten/extended.  I did a 
simple test of what I thought might produce unexpected results, but in fact 
worked exactly as I wanted it to!  Bravo guys... every time I think there 
might be a (very slight) hole in the design of the language, I am proven 
wrong.  :)

Here's the test, which ensures that code from within that module will 
always call a "clean" group of functions (even when a function is 
exported!)... i.e. you can't change/replace the internal dispatch from 
outside the module, which was my primary concern.  Check out the numbers 
highlighted in orange.  If the internal call to _f(x) could be masked, they 
should be -1... however that's not allowed so it (correctly) returns 999.

In summary... please ignore all my comments above about private functions 
since it already works the way I want, and thanks for teaching me a little 
more about the language.  


julia> module A
       export f, _f
       f(x) = _f(x)
       _f(x) = 999
       end

julia> using A

julia> A.f(0), A.f(0.0), A._f(0), A._f(0.0)
(999,999,999,999)

julia> f(0), f(0.0),_f(0), _f(0.0)
(999,999,999,999)

julia> A._f(x::Float64) = -1
_f (generic function with 2 methods)

julia> A.f(0), A.f(0.0), A._f(0), A._f(0.0)
(999,*999*,999,-1)

julia> f(0), f(0.0),_f(0), _f(0.0)
(999,999,999,-1)




On Friday, May 1, 2015 at 8:57:04 PM UTC-4, [email protected] wrote:
>
>
>
> On Friday, May 1, 2015 at 11:39:20 PM UTC+10, Tom Breloff wrote:
>>
>> I agree that auto-merging could cause hard-to-find bugs for the user. 
>>  This is less important than causing impossible-to-find bugs for a package 
>> writer IMO.
>>
>
> I'm not sure I understand what impossible to find bug not merging 
> functions causes.
>
>  
>
>>
>> Here's a couple potential solutions for the user space issues:
>>
>>    - "@verbose using SomeHugeModule"
>>       - this could analyze the exported functions and check for name 
>>       clashes superficially (i.e. no concept of dispatch types) and print a 
>>       report of potentially dangerous method names
>>    - new syntax: "using SomeHugeModule without fragileMethod1, 
>>    fragileMethod2"
>>       - similar to "import A: x, y" but the reverse... allow everything 
>>       except those 2 methods to be imported
>>    
>> Note that for a user that just wants to use a module without worrying 
>> about safety, nothing changes.  However for users building more complex 
>> systems with many packages, they have a way to see potential clashes and 
>> decide on their own how best to handle them.  A "using ... without ..." 
>> syntax would be super nice for some larger packages that mostly have unique 
>> names exported, but may have a couple clashes.  Then you can do "using" and 
>> just add to the "without" list if any clashes become a problem.
>>
>
> The "without" syntax allows possible reductions in verbosity when 
> excluding a few names from the import, and makes them visible, so it is 
> useful, but it is only syntactic sugar, not any new solution.
>  
>
>>
>>
>> And here's an idea for the package writer issue:
>>
>> @includes_private Module A
>>
>> f(x) = "not too important"
>> _f(x) = "important... must call this internally"  # NOTE: the underscore 
>> tells the @includes_private macro to "hide" this function from the outside 
>> world
>>
>> function g()
>>   bigobj = createHugeObject()
>>   f(bigobj)
>>   _f(bigobj) # we should be able to guarantee that this calls our 
>> function above... even if someone defines A._f(x) elsewhere
>> end
>>
>
> Julia experts should correct me, but it is my understanding that within 
> the module it will always call the definition local to the module (unless 
> you import explicitly).  To quote the manual "Within a module, you can 
> control which names from other modules are visible (via importing)".
>
>  
>
>>
>>
>> end
>>
>> using A
>> f(x) = "something orthogonal to A.f"
>> A._f(x) = "something else"  # NOTE: this should either not be allowed 
>> (hard) or at least not clash with A's _f(x)... maybe replacing _f with a 
>> gensym within A??
>> g()
>>
>>
>> I *think* these solutions are somewhat straightforward, and the only 
>> thing that would change core julia is the "without" syntax.  If changing 
>> syntax is not worth it, maybe you could make a "using_without" macro?
>>
>
> I don't really understand what the @include_private macro does and what 
> problem it solves.  Just don't export _f().
>  
>
>>
>> @using_without SomeHugeModule fragileMethod1 fragileMethod2
>>
>> And now that I think about it, you could combine these concepts into 
>> another macro which would analyze for name clashes and add any potentially 
>> dangerous method names to the without list:
>>
>> @safe_using SomeHugeModule
>>
>>
>>
>> Does this functionality exist already?  Are these macros something the 
>> community would want?  I would be willing to work on it.
>>
>>
>>
>>

Reply via email to