Not quite sure how to narrow down the audience to interested parties, so I’m placing this here.
LightGraphs 2.0 is in active development. One of the big changes is the movement of functions into separate submodules. (In combination with our expanded use of multiple dispatch, this makes for a pretty elegant approach.) However, we have some new issues relating to exports as a result, and I’d like the group’s opinion on the best way to proceed.
In short, we now have common functions that dispatch based on structures:
shortest_paths(g, 1, BellmanFord()) vs
shortest_paths(g, 1, Dijkstra()), for example. These methods and structs live in the
The problem is what to export from these submodules. My initial feeling is the answer should be “as little as possible, if anything”. The reason this is an issue is name conflicts on some of the structures that describe algorithms. Dijkstra and Tarjan, for example, were prolific graph researchers and contributed to the field in multiple ways, and are therefore defined in multiple submodules. This will cause a conflict if these structs are exported from each module, and the modules are used concurrently (either directly or transitively).
The impact of the decision is one of user-friendliness. That is, in a “export nothing” scenario, users would be moving from
using LightGraphs ... p = dijkstra_shortest_paths(g, 1)
using LightGraphs using LightGraphs.ShortestPaths: shortest_paths, Dijkstra ... p = shortest_paths(g, 1, Dijkstra())
using LightGraphs, LightGraphs.ShortestPaths ... p = ShortestPaths.shortest_paths(g, 1, ShortestPaths.Dijkstra())
option 1) export nothing
The second option is to keep the structures unexported, but export the functions/methods. This results in the ability to run the functions with the default algorithms (where they exist), or forcing the user to explicitly import an alternate algorithm.
option 2) export functions/methods only
The final options I can think of are to
option 3) export everything, and let the users deal with any conflicts, or
option 4) export everything and rename everything so that there are no conflicts
Neither of these last 2 options seem to be a good idea. The former may produce conflicts in transitive dependencies that the user is unaware of (
LightGraphs.Connectivity depends on
LightGraphs.ShortestPaths which depends on
LightGraphs.Traversals); the latter will eventually be unsustainable as new algorithms get included in the package.
- Option 1: export nothing
- Option 2: export functions/methods only
- Option 3: export everything and let users deal with name conflicts
- Option 4: export everything and rename conflicting structs
- Option 5: something else (see below)
Edited to add: an additional advantage of option 2 is that we have an explicit way to publish the API: that is, exported functions are part of the API; unexported functions aren’t and can change without causing a breakage. Option 1 doesn’t have this ability and we’d have to figure out another way to mark functions as part of the official API.
Feel free to add comments / ask questions below. Thanks for the help.