typed icon indicating copy to clipboard operation
typed copied to clipboard

Right way to call assertions inside assertions

Open latot opened this issue 2 years ago • 3 comments

Hi all, I was thinking, what would be the appropriate way to call an assertion inside other one, like in List, the each param.

Actually what does List/Data.frame is just call it and ignore the value, which is not exactly ideal for R, because call a value directly can also means be a possible return value, use a tmp variable seems an option but I think is not ideal.

custom_assert <- as_assertion_factory(function(value, f) {
  #Ideally skip this way
  f(value)

  #use invisible
  invisible({f(value)})

  #tmp var
  tmp <- f(value)

  #just assign to value
  #for now, assertions does not change the values
  #is not planned too as you said, still reassign a value is not
  #ideal too, but better than put the value as possible return
  value <- f(value)

  value
}

Is there a better way for this?

Thx!

latot avatar Oct 13 '23 14:10 latot

I don't understand what you are tying to do here

moodymudskipper avatar Nov 25 '23 17:11 moodymudskipper

When we create a custom assertion, we can also use other assertions for it, but what would be the right way to call an assertion that is used internally?

f represents an assertion we want to use internally, the example above shows 3 ways to call the assertion, which each of them has itsn own benefits and detriments:

  • f(value): In R, return a value like this is prone to bugs, when someone edit the code who is not who design it, can miss a line like that and put a new return value some where else, is not recommended (in strong types langs maybe can be managed by the compiler, here not).
  • invisible: we can use invisible to hide the result of f, trick to avoid return a value (?
  • value <- f(value): This one is the most clear and redundant, the idea is f to not change the value, as you described any type should never change the input, is also redundant to assign/replace a value.

I don't think any of the three cases are "perfect", if you ask me, maybe would be better to a assertion not return anything, if the input value never change avoid the need to return the value would even clarify how to write custom assertions and this workflows (all returns would be NULL/no return).

Is just some ideas, if you think there is a clear way would be great to know and write it on docs.

As a note, the idea is to use assertions internally, assertion(~other_assertion(value)) is like an "external use". great not for what I wrote this issue.

Thx!

latot avatar Nov 27 '23 13:11 latot

  • invisible() works only when print() is called, here as I understand it has no effect.
  • There is no point in assigning to a tmp variable you wouldn't use
  • since assertions are called mainly for side effects there is no problem if we don't assign the input, so I'd say the first one is perfectly fine, I don't get how this would be prone to bugs, maybe a realistic example would help

moodymudskipper avatar Dec 02 '23 10:12 moodymudskipper