Guard (computer science)

Last updated

In computer programming, a guard is a boolean expression that must evaluate to true if the execution of the program is to continue in the branch in question. Regardless of which programming language is used, a guard clause, guard code, or guard statement is a check of integrity preconditions used to avoid errors during execution.

Contents

Uses

A typical example is checking that a reference about to be processed is not null, which avoids null-pointer failures.

Other uses include using a boolean field for idempotence (so subsequent calls are nops), as in the dispose pattern.

publicstringFoo(stringusername){if(username==null){thrownewArgumentNullException(nameof(username),"Username is null.");}// Rest of the method code follows here...}

Flatter code with less nesting

The guard provides an early exit from a subroutine, and is a commonly used deviation from structured programming, removing one level of nesting and resulting in flatter code: [1] replacing if guard { ... } with if not guard: return; ....

Using guard clauses can be a refactoring technique to improve code. In general, less nesting is good, as it simplifies the code and reduces cognitive burden.

For example, in Python:

# This function has no guard clausedeff_noguard(x):ifisinstance(x,int):#code#code#codereturnx+1else:returnNone# Equivalent function with a guard clause. Note that most of the code is less indented, which is gooddeff_guard(x):ifnotisinstance(x,int):returnNone#code#code#codereturnx+1

Another example, written in C:

// This function has no guard clauseintfuncNoGuard(intx){if(x>=0){//code//code//codereturnx+1;}else{return0;}}// Equivalent function with a guard clauseintfuncGuard(intx){if(x<0){return0;}//code//code//codereturnx+1;}

Terminology

The term is used with specific meaning in APL, Haskell, Clean, Erlang, occam, Promela, OCaml, Swift, [2] Python from version 3.10, and Scala programming languages.[ citation needed ] In Mathematica, guards are called constraints. Guards are the fundamental concept in Guarded Command Language, a language in formal methods. Guards can be used to augment pattern matching with the possibility to skip a pattern even if the structure matches. Boolean expressions in conditional statements usually also fit this definition of a guard although they are called conditions.

Mathematics

In the following Haskell example, the guards occur between each pair of "|" and "=":

fx|x>0=1|otherwise=0

This is similar to the respective mathematical notation:

In this case the guards are in the "if" and "otherwise" clauses.

Multiple guards

If there are several parallel guards, they are normally tried in a top-to-bottom order, and the branch of the first to pass is chosen. Guards in a list of cases are typically parallel.

However, in Haskell list comprehensions the guards are in series, and if any of them fails, the list element is not produced. This would be the same as combining the separate guards with logical AND, except that there can be other list comprehension clauses among the guards.

Evolution

A simple conditional expression, already present in CPL in 1963, has a guard on first sub-expression, and another sub-expression to use in case the first one cannot be used. Some common ways to write this:

(x>0) -> 1/x; 0 x>0 ? 1/x : 0

If the second sub-expression can be a further simple conditional expression, we can give more alternatives to try before the last fall-through:

(x>0) -> 1/x; (x<0) -> -1/x; 0

In 1966 ISWIM had a form of conditional expression without an obligatory fall-through case, thus separating guard from the concept of choosing either-or. In the case of ISWIM, if none of the alternatives could be used, the value was to be undefined, which was defined to never compute into a value.

KRC, a "miniaturized version" [3] of SASL (1976), was one of the first programming languages to use the term "guard". Its function definitions could have several clauses, and the one to apply was chosen based on the guards that followed each clause:

facn=1,n=0=n*fac(n-1),n>0

Use of guard clauses, and the term "guard clause", dates at least to Smalltalk practice in the 1990s, as codified by Kent Beck. [1]

In 1996, Dyalog APL adopted an alternative pure functional style in which the guard is the only control structure. [4] This example, in APL, computes the parity of the input number:

parity{2:'odd''even'}

Pattern guard

In addition to a guard attached to a pattern, pattern guard can refer to the use of pattern matching in the context of a guard. In effect, a match of the pattern is taken to mean pass. This meaning was introduced in a proposal for Haskell by Simon Peyton Jones titled A new view of guards in April 1997 and was used in the implementation of the proposal. The feature provides the ability to use patterns in the guards of a pattern.

An example in extended Haskell:

clunkyenvvar1var2|Justval1<-lookupenvvar1,Justval2<-lookupenvvar2=val1+val2-- ...other equations for clunky...

This would read: "Clunky for an environment and two variables, in case the lookups of the variables from the environment produce values, is the sum of the values. ..." As in list comprehensions, the guards are in series, and if any of them fails the branch is not taken.

See also

Related Research Articles

In programming language theory, lazy evaluation, or call-by-need, is an evaluation strategy which delays the evaluation of an expression until its value is needed and which also avoids repeated evaluations.

In computer science, control flow is the order in which individual statements, instructions or function calls of an imperative program are executed or evaluated. The emphasis on explicit control flow distinguishes an imperative programming language from a declarative programming language.

In computer programming, specifically when using the imperative programming paradigm, an assertion is a predicate connected to a point in the program, that always should evaluate to true at that point in code execution. Assertions can help a programmer read the code, help a compiler compile it, or help the program detect its own defects.

A list comprehension is a syntactic construct available in some programming languages for creating a list based on existing lists. It follows the form of the mathematical set-builder notation as distinct from the use of map and filter functions.

In computer programming, indentation style is a convention, a.k.a. style, governing the indentation of blocks of source code. An indentation style generally involves consistent width of whitespace before each line of a block, so that the lines of code appear to be related, and dictates whether to use space or tab characters for the indentation whitespace.

<span class="mw-page-title-main">Conditional (computer programming)</span> Control flow statement that executes code according to some condition(s)

In computer science, conditionals are programming language commands for handling decisions. Specifically, conditionals perform different computations or actions depending on whether a programmer-defined Boolean condition evaluates to true or false. In terms of control flow, the decision is always achieved by selectively altering the control flow based on some condition . Although dynamic dispatch is not usually classified as a conditional construct, it is another way to select between alternatives at runtime. Conditional statements are the checkpoints in the programme that determines behaviour according to situation.

In functional programming, a monad is a structure that combines program fragments (functions) and wraps their return values in a type with additional computation. In addition to defining a wrapping monadic type, monads define two operators: one to wrap a value in the monad type, and another to compose together functions that output values of the monad type. General-purpose languages use monads to reduce boilerplate code needed for common operations. Functional languages use monads to turn complicated sequences of functions into succinct pipelines that abstract away control flow, and side-effects.

In computer programming, the ternary conditional operator is a ternary operator that is part of the syntax for basic conditional expressions in several programming languages. It is commonly referred to as the conditional operator, ternary if, or inline if. An expression a ? b : c evaluates to b if the value of a is true, and otherwise to c. One can read it aloud as "if a then b otherwise c". The form a ? b : c is the most common, but alternative syntax do exist; for example, Raku uses the syntax a ?? b !! c to avoid confusion with the infix operators ? and !, whereas in Visual Basic .NET, it instead takes the form If(a, b, c).

Short-circuit evaluation, minimal evaluation, or McCarthy evaluation is the semantics of some Boolean operators in some programming languages in which the second argument is executed or evaluated only if the first argument does not suffice to determine the value of the expression: when the first argument of the AND function evaluates to false, the overall value must be false; and when the first argument of the OR function evaluates to true, the overall value must be true.

In computer science, the Boolean is a data type that has one of two possible values which is intended to represent the two truth values of logic and Boolean algebra. It is named after George Boole, who first defined an algebraic system of logic in the mid 19th century. The Boolean data type is primarily associated with conditional statements, which allow different actions by changing control flow depending on whether a programmer-specified Boolean condition evaluates to true or false. It is a special case of a more general logical data type—logic does not always need to be Boolean.

The computer programming languages C and Pascal have similar times of origin, influences, and purposes. Both were used to design their own compilers early in their lifetimes. The original Pascal definition appeared in 1969 and a first compiler in 1970. The first version of C appeared in 1972.

The programming language APL is distinctive in being symbolic rather than lexical: its primitives are denoted by symbols, not words. These symbols were originally devised as a mathematical notation to describe algorithms. APL programmers often assign informal names when discussing functions and operators but the core functions and operators provided by the language are denoted by non-textual symbols.

<span class="mw-page-title-main">Recursion (computer science)</span> Use of functions that call themselves

In computer science, recursion is a method of solving a computational problem where the solution depends on solutions to smaller instances of the same problem. Recursion solves such recursive problems by using functions that call themselves from within their own code. The approach can be applied to many types of problems, and recursion is one of the central ideas of computer science.

The power of recursion evidently lies in the possibility of defining an infinite set of objects by a finite statement. In the same manner, an infinite number of computations can be described by a finite recursive program, even if this program contains no explicit repetitions.

Platform Invocation Services, commonly referred to as P/Invoke, is a feature of Common Language Infrastructure implementations, like Microsoft's Common Language Runtime, that enables managed code to call native code.

The conditional operator is supported in many programming languages. This term usually refers to ?: as in C, C++, C#, and JavaScript. However, in Java, this term can also refer to && and ||.

The null coalescing operator is a binary operator that is part of the syntax for a basic conditional expression in several programming languages, such as : C# since version 2.0, Dart since version 1.12.0, PHP since version 7.0.0, Perl since version 5.10 as logical defined-or, PowerShell since 7.0.0, and Swift as nil-coalescing operator.

List comprehension is a syntactic construct available in some programming languages for creating a list based on existing lists. It follows the form of the mathematical set-builder notation as distinct from the use of map and filter functions.

This article describes the features in the programming language Haskell.

In programming jargon, Yoda conditions is a programming style where the two parts of an expression are reversed from the typical order in a conditional statement. A Yoda condition places the constant portion of the expression on the left side of the conditional statement.

In certain computer programming languages, the Elvis operator, often written ?:, is a binary operator that returns the evaluated first operand if that operand evaluates to a value likened to logically true, and otherwise returns the evaluated second operand. This is identical to a short-circuit or with "last value" semantics. The notation of the Elvis operator was inspired by the ternary conditional operator, ? :, since the Elvis operator expression A ?: B is approximately equivalent to the ternary conditional expression A ? A : B.

References

  1. 1 2 Beck, Kent (1997). "Guard Clause". Smalltalk Best Practice Patterns,. pp. 178–179.
  2. Cook, Nate. "guard & defer". NSHipster. Retrieved 2016-02-26.
  3. Turner, D. A. "Some History of Functional Programming Languages" (PDF).
  4. Scholes, John. "Direct Functions in Dyalog APL" (PDF).