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

Convenience props #433

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft

Convenience props #433

wants to merge 2 commits into from

Conversation

lawremi
Copy link
Collaborator

@lawremi lawremi commented Aug 31, 2024

@t-kalinowski here are the convenience property constructors that we discussed. They seem useful in my applications of S7; however, that does not necessarily mean that they belong in the base S7 package. Curious about everyone's thoughts.

@hadley
Copy link
Member

hadley commented Sep 27, 2024

Sorry, I missed this! I've been thinking about this too for elmer, whose classes have almost entirely scalar properties. I do think that this does belong in S7 because scalar values are such a common need and we don't currently offer any help.

My model for thinking about this is based on the check_* functions that we've implementing in rlang, and embed into most tidyverse packages: https://github.com/r-lib/rlang/blob/main/R/standalone-types-check.R. We use them a lot so they're pretty battle tested.

For this discussion, I think the most relevant are:

  • check_bool(), equivalent to your new_flag_property()
  • check_string(), equivalent to your new_string_property().
  • check_number_decimal(), equivalent to your new_number_property().
  • check_number_whole(), equivalent to your new_int_property().

A few thoughts based on comparing our code to your properties:

  • We should negotiate on the names to get something we're both happy with 😄

  • All our checks have an allow_na = FALSE and allow_null = FALSE argument. These turn out to be pretty useful defaults since most of the time (at least in our experience) scalars shouldn't be missing, and it's nice to have an easy way to make them optional. We also have allow_empty for check_string(), and that comes up quite frequently.

  • I don't think scalar properties should have a default (unless they're nullable/optional). There's an obvious default for a vector (a zero length instance), but I don't think that's the case for scalars.

  • We spent a bunch of time to come up with _number_whole() vs _number_decimal() and I like how they focus on the type of number rather than the type of the underlying storage. As you point out, forcing users to supply literal integers is rather hostile.

  • I'd be tempted to give these property constructors a scalar_ prefix, because I think that's a nice constrast with the typical class_ prefix, e.g.

    new_class("foo", properties = list(
      x = class_numeric,
      open = scalar_bool(),
      times = scalar_number_whole()
    ))
  • Maybe it's worth having an explicit scalar_enum() property? That would correspond to match.arg() or rlang::arg_match() (which is similar but doesn't do partial matching and includes an error message that uses string distance to suggest which option you might have wanted.)

  • I think we should discuss the list checker in more detail because I think it's useful to also be able to provide the specific names you expect. But then you need some way to say if any additional names are ok too.

  • I do wonder if it's worth including something for paths, since that's also a common need.

Thanks for working on this and I look forward to discussing it more 😄

@lawremi
Copy link
Collaborator Author

lawremi commented Sep 28, 2024

Thanks for your comments. They all seem reasonable to me. I don't feel that strongly about the details, as long as the convenience and code clarity remains. The only reason I messed around with default defaults is that they weren't hurting anything, but I agree it might be better to force the developer to be explicit.

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

Successfully merging this pull request may close these issues.

2 participants