mbojan / rgraph6

Encoding graphs in graph6, sparse6, and digraph6 formats
https://mbojan.github.io/rgraph6/
GNU General Public License v3.0
12 stars 3 forks source link

To class or not to class #13

Closed mbojan closed 3 years ago

mbojan commented 4 years ago

At this moment the vector of graph6 symbols has its own S3 class extending character, i.e. class is c("graph6", "character"). It turns out it is dropped on some occasions, for example when vapply()ing and replicate()ing or c()oncatenating. Perhaps

  1. Drop the class altogether and just return character vectors.
    • will need to implement some checks in as_adjacency() if a string is indeed a graph6 symbol
  2. Add some methods e.g. c.graph6. A little bit like with the Date class.
    • make sure what the minimally-required set of additional methods is necessary to avoid hiccups.
schochastics commented 4 years ago

This is a good question. In my fork I currently also use a dgraph6 class. It makes coding a bit easier with as_adjacency.

But technically, I think, there is no need for classes. E.g.: dgraph6 always starts with "&" and sparse6 always with ":" .

Not sure what the best/most convenient move is since it is the first time I actually work with classes.

mbojan commented 4 years ago

This is a good question. In my fork I currently also use a dgraph6 class. It makes coding a bit easier with as_adjacency.

Yes, exactly.

But technically, I think, there is no need for classes. E.g.: dgraph6 always starts with "&" and sparse6 always with ":" .

So does that mean you can always tell dgraph6 from sparse6 and from graph6 by the initial byte?

Not sure what the best/most convenient move is since it is the first time I actually work with classes.

Let's stick with the class for now. At first I was afraid if it will lead to writing a lot of vacuous code that just apply the class to character vectors. Perhaps it is not that bad.

I think I will add as_graph6.character() with some tests/heuristics if a string is indeed an appropriate symbol. as_dgraph6.character() and as_sparse6.character() could then check if the first character is & or : respectively.

schochastics commented 4 years ago

Yes the formats are always distinguishable by the first byte.

All right I'll put in sparse6 as its own class then too

mbojan commented 4 years ago

Yep.

mbojan commented 4 years ago

Rethinking

But technically, I think, there is no need for classes. E.g.: dgraph6 always starts with "&" and sparse6 always with ":" .

Another benefit of

is that one could have a vector of graph6, drgaph6, and sparse6 symbols inter-mixed and then just lapply to get a list of matrices or igraphs and so on. In either case we would need a function that given a string recognizes the format or shouts that it is something else.

mbojan commented 4 years ago

Whatever the detailed approach, the umbrella name could be something like asciigraph.

What do you think @schochastics ?

schochastics commented 4 years ago

The more I think about it, the more I prefer the non-class approach. You made a very good point with vectors containing a mixture of graph6/sparse6/dgraph6! To figure out the format we just need to check the first bit. so as_adjacency and as_elist should be easy to adapt.

Other question: If this is the way to go, should the package then still include as_sparse6(), as_graph6(), etc, or just one function with a parameter "type"?

Something like graph_ascii(obj, type=c("graph6","dgraph6","sparse6")). The as_* functions would then just be called under the hood. What do you think?

mbojan commented 3 years ago

Opted for as_sparse6(), as_graph6() and as_digraph6() for the one way and igraph_from_text() and network_from_text() for the other way. They guess what the symbol is (can be mixed). Low-level funs are network_from_{graph6|sparse6|digraph6}() and igraph_from_{graph6|sparse6|digraph6}().