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.
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.
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
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?
@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.
On Thursday, April 30, 2015 at 10:44:29 PM UTC-4, [email protected] wrote:
>
>
>> Are there other pitfalls to auto-merging in user-space-only?
>>
>>
>>>>
> Tom,
>
> The problem with auto merging in user code (as I see it)
>
> module a
> export f
> f(x) = 4
> f(x::Int)=5
>
> user code:
>
> using a
> f(5) # gives 5 fine
> f(6.0)+1 # gives 5 fine
> f(5.0) # gives 4, fine
>
> now another module:
>
> module b # totally separate from a, a and b have nothing in common except
> both use the verb f
> export f
> f(x::Float64) = "four"
>
> user code:
>
> using a,b # assuming methods of f() are auto-merged in user space
>
> # existing code
>
> f(5) # still gives 5, ok
> f(6.0)+1 # can't add string and int, at least this breaks noisily
> f(5.0) # "four"?, existing code is silently changed :(
>
> Consider also how much more complex the problem becomes if f() is generic,
> how many f{T}(x::T) exist and have to be merged? Don't know, depends on
> usage.
>
>