Open In App

Scala | Preconditions(assert, assume, require, ensuring)

Last Updated : 09 Dec, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Preconditions refer to some conditions in Scala that need to be fulfilled before going further with any code or program. In Scala, the process of Designing by Contract(DbC), a software designing process gives significance and meaning to Scala preconditions. The above approach was given by Bertrand Meyer and it offers some post conditions and preconditions to a code block which if not satisfied, throws an exception. Scala preconditions are a set of major functions that have different conditions a programmer must follow while designing a software. These functions come in Predef.scala package and one does not have to import any separate package. The methods are :

  1. Assert – For general assertions
  2. Assume – Stating an Axiom
  3. Require – Specifically checking inputs
  4. Ensuring – is a post condition that has also been covered.
  • Assert Assert method puts a necessity for a condition to be satisfied while performing a certain action. If this condition is satisfied, then the code works fine, otherwise it throws an exception. The exceptions are checked at run time. The assert() method is thus a way to dynamically check the invariants. The above method takes a Boolean statement as a parameter and checks throughout the program if anywhere it is violated. it throws out an exception or an assertion error. Consider the following program as a part of Driver’s license approval of application process. It produces error if the applicant age is not equal to or more than 18. 

Scala




// Code to check the age of the applicant
val applicant_age = 16
 
// assert method calling
assert(applicant_age>17)


  • If the age is past the require minimum, the process is moved forward, otherwise, the program throws an Exception as below:
Exception in thread "main" java.lang.AssertionError: assertion failed
  • Looking up for the code for the same in Predef.scala, one would find a similar code like above: 

Scala




def assert(assertion: Boolean) {
  if (!assertion)
    throw new java.lang.AssertionError("assertion failed")
}


  • Assume Assume method is expected to be consumed by static analysis tools. It is supposed to limit down the number of conditions that have to be checked for execution of a program. If the assume condition is violated, the checker, silently leaves the path and doesn’t allow the program to go much deeper. The assume() method has the same syntax as the previously mentioned assert(), the only difference being its execution. The following example talks about a program that executes assuming that the age of the applicant is in any case greater than or equal to 18. The main code had been avoided and only the code containing the call to assume() is incorporated. 

Scala




// Code to check the age of the applicant
license_approval(17)
 
// Method to approve the License application
def license_approval(applicant_age:Int) {
 
  assume(applicant_age>=18)
//……………
//…………
//…………
//The main code for checking the other details of the applicant.
//……………
//…………
//…………
}


  • The assume() method gives the static checker an axiom that it could rely upon. This reduces the burden on the checker. The program runs deeper into the code if the Boolean condition of the assume() parameter is satisfied, otherwise, it throws an exception:
Exception in thread "main" java.lang.AssertionError: assumption failed
  • The similar code can be found inside the Predef.scala package: 

Scala




def assume(assumption: Boolean) {
  if (!assumption)
    throw new java.lang.AssertionError("assumption failed")
}


  • While assert() is a method of asserting a condition in all execution paths or to check an invariant condition throughout the program, assume(), on the other hand, is used to reduce the load on the static analyser. It works locally to develop a divide-and-rule mechanism to help the analyzers to assume a condition and go through checking the code.
  • Require: This method has an innovative mode of dealing with the problem. It usually blames the method caller if a certain condition is not satisfied. If the condition is satisfied, the program goes on executing, if it does not, it throws an exception. The syntax is the same as before for assert() and assume() following a Boolean condition as the parameter. The working of the require() function can be shown with an example: The following example shown a method to double any odd number. If the number passed in the function is odd, it works smoothly, if not, then an exception is thrown. 

Scala




// Code to double the odd numbers
def double_odd_numbers(number:Int) : Int = {
 
    require(number%2==1) // Checking if the number is odd using assume method
 
    number * 2;
 
}
// Calling function
double_odd_numbers(13)


  • If the condition is not satisfied, the following exception is thrown:
Exception in thread "main" java.lang.IllegalArgumentException: requirement failed
  • Looking up for the code for exception in Predef.scala, we come across the following code: 

Scala




def require(requirement: Boolean) {
  if (!requirement)
    throw new IllegalArgumentException("requirement failed")
}


  • Ensure: Ensure is a post-condition unlike the others. This method is usually applied along with the require() method to make a workable program. Considering the above example itself, we can modify the code by adding an ensure condition which requires the input number to be less than a certain limit. 

Scala




// Code to double the odd numbers
def double_odd_numbers(number:Int, lmt:Int) : Int = {
 
    require(number%2==1) // Checking if the number is odd using assume method
 
    number * 2;
 
} ensuring(number * 2 < lmt) // Ensuring that the number produced is less than the limit.
 
// Calling function
// The method also requires a limit [parameter to be passed.
double_odd_numbers(13, 100)


  • The assert() method thus requires that the checker must prove the condition that follows as a parameter, assume(), on the other hand, helps checker to reduce the burden by assuming that a certain condition holds true. While, the require() method specifies the condition that has to be followed by the caller of the function. If the programmer seeks to remove the exceptions generated by the assume() and assert() methods, one can use the -Xdisable-assertions command to do so.


Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads