stevedlawrence commented on code in PR #1058:
URL: https://github.com/apache/daffodil/pull/1058#discussion_r1276182844


##########
daffodil-japi/src/main/scala/org/apache/daffodil/japi/Daffodil.scala:
##########
@@ -886,3 +887,18 @@ object DaffodilXMLEntityResolver {
     DFDLCatalogResolver.get
   def getLSResourceResolver: org.w3c.dom.ls.LSResourceResolver = 
DFDLCatalogResolver.get
 }
+
+/**
+ * Provides functions for assertions for API usage
+ */
+object Assertions {
+
+  /**
+   * Argument check for API functions
+   * @param testFailsIfFalse test that causes failure when false
+   * @param message message to be displayed on failure of assertion
+   */
+  def argCheck(testFailsIfFalse: Boolean, message: String): Unit = {
+    Assert.argCheck(testFailsIfFalse, message)
+  }
+}

Review Comment:
   Assert.argCheck doesn't really call the macro, it **is** the macro. This 
function ends up being converted to something like this once the macro is 
expanded:
   
   ```scala
   def argCheck(testFailsIfFalse: Boolean, message: String): Unit = {
     if (!testFailsIfFalse) {
       throw new IllegalStateException(message)
     }
    }
   ```
   So calling something like
   ```scala
   Assertions.argCheck(!isError, s"Some $expensive string to evaluate")
   ```
   Will force evaluation of of the test and the string and pass the results 
into the argCheck where it then does the test/throw. So it's forcing evaluating 
of a string that might be expensive and likely will never even be used since 
the condition will rarely fail.
   
   However, if something calls `Assert.argCheck` directly, e.g.
   ```scala
   Assert.argCheck(!isError, s"Some $expensive string to evaluate")
   ```
   Then macro expansion causes this to become something like this:
   ```scala
   if (!isError) {
     throw new IllegalStateException(s"Some $expensive string to evaluate")
   }
   ```
   So if the condition never fails, we never evaluate that string.
   
   Maybe @mbeckerle was suggesting this new function should be called from the 
daffodil-sapi instea of daffodil-core, so the checks are done in the public API 
themselves? Or if we want o have the `Assertions` thing here as part of the 
public API, then it needs to be something like
   ````scala
   object Assertions {
     def argCheck(...) = macro argCheck
   }
   ```
   The macro keyword makes this a special macro, and calls of the function 
don't actuall call the function be instead expand the macro where the function 
is called. It's sort of like in-lining the function.
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to