Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support typed lib #2229

Closed
latot opened this issue Sep 8, 2023 · 3 comments
Closed

Support typed lib #2229

latot opened this issue Sep 8, 2023 · 3 comments

Comments

@latot
Copy link

latot commented Sep 8, 2023

Hi, the background can be found here luukvdmeer/sfnetworks#255.

The summary, the "typed" helps to force types of data on variables and function's parameters, which is great to finally get order on R's code.

The feature request, is support inside sf the data types of it.

As example:

typed_geometry <- typed::as_assertion_factory(function(
  value,
  types = NULL
){

  if (!inherits(value, "sfg")) {
    e <- sprintf(
    "%s\n%s",
    "Not geometry",
    waldo::compare(
        class(value),
        "sfg",
        x_arg = "class(value)",
        y_arg = "expected"))
    stop(e, call. = FALSE)
  }

  if (!is.null(types)) {
    val_type <- as.vector(sf::st_geometry_type(value))

    if (!(val_type %in% types)) {
      e <- sprintf(
      "%s\n%s",
      "Wrong geometry type",
      waldo::compare(
          val_type,
          types,
          x_arg = "sf::st_geometry_type(value)",
          y_arg = "expected"))
      stop(e, call. = FALSE)
    }
  }

  value

})

Now can create variable a params where we only accept geomtries, and we can say which want must be:

library(typed)
typed_geometry(types = c("LINESTRING", "MULTILINESTRING")) ? x

#works
x <- sf::st_linestring()
x <- sf::st_multilinestring()

#not works
x <- sf::st_point()
x <- NA

#A function which join two continuous linestrings
#it should have only linetrings as inputs, and the output
#must be a linestring too, multilinestring would means
#a non continuous lines
f  <- typed_geometry(type = "LINESTRING") ? function(
 geom1 = ? typed_geometry(type = "LINESTRING"),
 geom2 = ? typed_geometry(type = "LINESTRING")
){
 sf::st_sfc(geom1, geom2) %.>%
 sf::st_multilinestring(.) %.>%
 sf::st_line_merge(.)
}

I have created a sample, which has SF, SFC, SFG, in order to do it works SF, I have created a custom Data.frame assertion, which allow us to check custom assertions by columns.

The feature request is have inside the package something like sf::typed_geometry or similar functions, so we can use typed objects with the project.

typed_sf.zip

Thx

@edzer
Copy link
Member

edzer commented Sep 8, 2023

That would draw in two direct, and several more indirect dependencies. Can this also be done in an add-on package, like sftypes or so, or is there a reason this can only be done inside sf?

@latot
Copy link
Author

latot commented Sep 8, 2023

There is no hard reason to be inside nor out of the SF package.

But there is some considerations I think would be great to think of.

  • How the types are from SF, the best would be SF's teams to create the assumptions, in case there is a new type, it can be added naturally
  • I think is natural get from SF package get their data types and not from an add-on package.
  • There is not a lot of types with the packages, IIRC sf has only 3 types of data, there is other cases like sfnetworks, which seems to have only one type of data, have a full new package for every lib when there is so few functions...

I think that would be the main reasons, I think an addon package would be the case if a package has several types, but not that great if there is only a few them.

@edzer
Copy link
Member

edzer commented Sep 8, 2023

I'll give it a thought when I have time to explore this. Another thing I'd like to explore is R7, which is also about stricter type handling afaict.

@edzer edzer closed this as completed Sep 8, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants