LightGraphs users (and other interested parties): please opine below

anon94023334
Wed, 15 Apr 2020 18:45:22 +0000
Graphs

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 LightGraphs.ShortestPaths submodule.

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)

to

using LightGraphs
using LightGraphs.ShortestPaths: shortest_paths, Dijkstra
...
p = shortest_paths(g, 1, Dijkstra())

or even

using LightGraphs, LightGraphs.ShortestPaths
...
p = ShortestPaths.shortest_paths(g, 1, ShortestPaths.Dijkstra())

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

Opinions please.

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)

Click to view the poll.

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.

26 posts - 11 participants