stchang / graph

Generic graph library and algorithms for Racket.
Apache License 2.0
58 stars 21 forks source link

Typed Racket interface #58

Open scolobb opened 3 years ago

scolobb commented 3 years ago

I would to connect the generic graph library with Typed Racket code. I started a package here: https://git.marvid.fr/scolobb/typed-graph

Right now I'm trying to add matrix graphs to typed-graph, and I am somewhat stuck at the matrix-graph macro. I can import it without any problem, but since it expands to a constructor of the matrix-graph struct, Typed Racket wants to have a type for that struct, which I don't know how to produce, because graph does not export it.

I can see the following ways to go, in order of my preference:

  1. Add a function to the graph library to create matrix graphs from a matrix, in addition to the matrix-graph macro. In this way, typed-graph can construct matrix graphs via an opaque function call, and even have a macro expanding to that function call, similarly to the original matrix-graph.

  2. Omit matrix graphs from the typed interface. (I don't personally use them).

  3. Export the matrix-graph struct. This is probably unwanted, because the struct seems to be part of the inner workings of the library.

  4. Add types directly to the graph library code base. This would require serious changes to the architecture of the library, in particular because Typed Racket doesn't directly support generics AFAIK. This option is probably an overkill for anyone who just wants to casually use graph from Typed Racket code.

What do you think?

Clearly, I am willing to submit the corresponding pull requests.

stchang commented 3 years ago

Thanks for starting this effort! I think the easiest thing to do would be the first one, adding a constructor function.

@bennn Did you run into anything like this when using the graph library with Typed Racket? Is there a recommended way to handle these kinds of situations when porting libraries to TR?

bennn commented 3 years ago

Number 1 (constructor function) sounds best to me too.

I never ran into matrix-graphs, but I did have trouble with other macros. A constructor function was the best way to fix.

(Typed Racket has an internal tool make-template-identifier to handle macros, but I don't think it's a good idea to try using it here.)

scolobb commented 3 years ago

Thank you @bennn for your answer!

scolobb commented 3 years ago

Hi. I've been somewhat away from this project lately, so I decided to give you an update, for your interest, but mostly to push myself to work on it :-)

Back in May, I submitted the PR #59 adding the function matrix->matrix-graph. It shouldn't be too hard to review.

Since then, I went on adding types for other functions. When I ran into bfs/generalized, I realized that I should I probably also write some types for gen-queue-lib. This is where I stopped and I plan to restart working.

I looked into graph properties for quite some time, but finally decided to put them away for the time being. From what I understand, the challenge would consist in making the code to which the macros expand to type correctly, which may be tricky. I don't need most of the macros in my personal use cases as of now, so I think I'd better go on with the lower hanging fruit.

scolobb commented 2 years ago

Hi. I have finished an incomplete Typed Racket interface! It's here: https://git.marvid.fr/scolobb/typed-graph.git . I also published it on the package catalog https://pkgd.racket-lang.org/pkgn/package/typed-graph and advertised it on the Racket Discourse: https://racket.discourse.group/t/typed-racket-interface-to-the-generic-graph-library/546 .

The interface is missing some of the nicest features of the library—the generic interface and the macros, but I decided that trying to get those to typecheck is beyond my needs for now.

Any feedback is welcome! :slightly_smiling_face:

bennn commented 2 years ago

Looks good!

I just converted my advent of code 2021 solutions for days 9, 12, and 15 to use typed-graph. Getting things to typecheck was easy after a few casts (e.g. casting a node from Any to String). All 3 run about as fast as the untyped versions. 👍

scolobb commented 2 years ago

Thank you for your feedback @bennn, I'm glad it works for you!