Skip to content

Enhance Rcpp::Nullable::as with explicit cast (Closes #1470)#1471

Open
eddelbuettel wants to merge 4 commits intomasterfrom
enhance/nullable
Open

Enhance Rcpp::Nullable::as with explicit cast (Closes #1470)#1471
eddelbuettel wants to merge 4 commits intomasterfrom
enhance/nullable

Conversation

@eddelbuettel
Copy link
Copy Markdown
Member

As discussed in #1470 and building on this morning's discussion at the bottom of #1451, we can make Nullable<T> a little nicer. And that is all this PR does: for cases where the implicit as<>() needs a nudge, we can hide the nudge inside that (member function) as() function body accessing the matching as<> for the given T. A little bit of ellbow grease.

Checklist

  • Code compiles correctly
  • R CMD check still passes all tests
  • Preferably, new tests were added which fail without the change
  • Document the changes by file in ChangeLog

Copy link
Copy Markdown
Member

@Enchufa2 Enchufa2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fine, although Nullable could be further improved. Having an as() method in the first place seems odd, because it deviates from the rest of the API. I.e., objects typically have T() and SEXP() operators. This one has the latter, and it would be nice to have the former for consistency instead of, or at least on top of, as(). Also typically set() and get() are private. See e.g. AttributeProxy, just to name something recent.

@eddelbuettel
Copy link
Copy Markdown
Member Author

eddelbuettel commented Apr 8, 2026

TBH I had forgotten these had as() and get() and I think they are barely used. The main use, and I just used it some more from another package, is just straight up instantiation as the T. I.e. in RQuantLib I let 'time to expiry' be either the double it always was (applied as 'time' relative to valuation date) or as a date and a number of functions now accomodate both types and then call this helper to determine the date:

QuantLib::Date getFutureDate(const QuantLib::Date today,
                             Rcpp::Nullable<double> maturity,
                             Rcpp::Nullable<QuantLib::Date> exDate) {
    if (exDate.isUsable()) {
        return Rcpp::as<QuantLib::Date>(exDate);
    } else if (maturity.isUsable()) {
        double mat = Rcpp::as<double>(maturity);
        // depending on the compile-time option, this is either intra-day or not
        // in minutes
        auto length = boost::posix_time::minutes(boost::uint64_t(mat * 360 * 24 * 60));
        return QuantLib::Date{today.dateTime() + length}; // high-res time ctos
    } else {
        Rcpp::stop("Excactly one of 'maturity' or 'exDate' needs to be supplied and be non-null.");
        return QuantLib::Date(); // not reached
    }
}

and I just realize I still need to rename today to evalDate or alike.

@eddelbuettel
Copy link
Copy Markdown
Member Author

eddelbuettel commented Apr 9, 2026

@enchufa You convinced me that operator T() is a good idea so I added that. But given that as() has been exposed for a decade I do not want to remove it overnight (also known as 'R Core-style' around here). I would be up for sticking deprecation warnings into as() if we think operator T() suits. As for get(), we could deprecate / hide at the same time.

PS Oh gnarl, may have to back that out or revisit as CI is unhappy.

@Enchufa2
Copy link
Copy Markdown
Member

Enchufa2 commented Apr 9, 2026

That's weird. Is it due to a different C++ standard with those versions?

@eddelbuettel
Copy link
Copy Markdown
Member Author

I honestly cannot work it out! But it is related to our Rcpp::String so it is a fair chance it is us. I am not sure I care.

You were right we want operator T. Back in the day we couldn't, apparently. Now we can, so now we do. Works for me.

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