Recent from talks
Nothing was collected or created yet.
Guard (computer science)
View on WikipediaIn 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.
The term guard clause is a Software design pattern attributed to Kent Beck who codified many often unnamed coding practices into named software design patterns, the practice of using this technique dates back to at least the early 1960s. The guard clause most commonly is added at the beginning of a procedure and is said to "guard" the rest of the procedure by handling edge cases upfront.
Uses
[edit]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.
public String foo(String username) {
if (username == null) {
throw new IllegalArgumentException("Username is null.");
}
// Rest of the method code follows here...
}
Flatter code with less nesting
[edit]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:
from typing import Any, Optional
# This function has no guard clause
def f_noguard(x: Any) -> Optional[int]
if isinstance(x, int):
# code here
return x + 1
else:
return None
# Equivalent function with a guard clause. Note that most of the code is less indented, which makes it easier to read and reason about
def f_guard(x: Any) -> Optional[int]
if not isinstance(x, int):
return None
# code here
return x + 1
Another example, written in C:
// This function has no guard clause
int funcNoGuard(int x) {
if (x >= 0) {
// code here
return x + 1;
} else {
return 0;
}
}
// Equivalent function with a guard clause
int funcGuard(int x) {
if (x < 0) {
return 0;
}
// code here
return x + 1;
}
Terminology
[edit]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
[edit]In the following Haskell example, the guards occur between each pair of "|" and "=":
f x
| 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
[edit]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
[edit]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:
fac n = 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
[edit]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:
clunky env var1 var2
| Just val1 <- lookup env var1
, Just val2 <- lookup env var2
= 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
[edit]- Assertion
- Guarded Command Language, a programming language based on non-deterministic conditionals
- Guarded suspension
- Iverson bracket
- Logical conditional
- Switch statement
References
[edit]- ^ a b Beck, Kent (1997). "Guard Clause". Smalltalk Best Practice Patterns,. pp. 178–179.
- ^ Cook, Nate. "guard & defer". NSHipster. Retrieved 2016-02-26.
- ^ Turner, D. A. "Some History of Functional Programming Languages" (PDF).
- ^ Scholes, John. "Direct Functions in Dyalog APL" (PDF).
External links
[edit]- Guard in Free On-Line Dictionary of Computing - FOLDOC, Denis Howe (editor).
- Guard Clause, WikiWikiWeb
- The Haskell 98 Report, chapter 3 Expressions.
- The Mathematica Book, section 2.3.5 Putting Constraints on Patterns
- The Glorious Glasgow Haskell Compilation System User's Guide, Version 6.4, section 7.3.2. Pattern guards
Guard (computer science)
View on GrokipediaFundamentals
Definition
In computer science, a guard is a Boolean expression that controls the execution of an associated statement or block of code by evaluating to true or false, thereby determining whether the statement runs.[6] This construct serves as a conditional gate, ensuring that the guarded code is only executed when the specified condition holds in the program's current state.[7] The basic structure of a guard pairs the Boolean condition with the statement it protects, often notated as<guard> → <statement>, where the guard is evaluated atomically before execution proceeds.[7] If the guard evaluates to true, the statement executes; otherwise, it is skipped, potentially allowing non-deterministic choice among multiple guards in a set.[6] Guards are typically designed to be side-effect-free to maintain predictability, though they can involve complex expressions as long as evaluation does not alter program state prematurely.[7]
For example, consider the pseudocode for selecting a positive value:
if x > 0 → print("positive")
if x > 0 → print("positive")
x > 0 must hold true for the print statement to execute, illustrating how guards enable precise conditional control without traditional branching overhead.[7] This mechanism, central to guarded command languages, facilitates clearer expression of program logic by decoupling condition evaluation from imperative flow.[6]
Terminology
In computer science, the primary term for this construct is "guard," typically denoting a boolean expression that determines eligibility for executing an associated code block or statement. Commonly extended as "guard clause" or "guard statement," it appears in imperative contexts for early validation and exit, while in conditional structures, it is occasionally termed a "predicate." Certain languages, such as Elixir, use "when clause" to denote equivalent guard mechanisms in pattern matching and function definitions.[8] Guards are distinguished from related concepts like preconditions in design-by-contract programming, which are runtime checks on inputs enforced before procedure invocation to ensure contractual obligations, often failing the program if violated; in contrast, guards enable conditional execution paths within the program flow without necessarily halting execution.[9] In contrast to assertions, which immediately terminate execution to enforce program invariants upon condition failure, guards support alternative execution paths without halting the program. Terminology varies by programming paradigm: in logic programming, guards are referred to as "conditions" within rules or clauses, facilitating selective commitment in parallel execution models like Guarded Horn Clauses.[10] In concurrent systems, they are known as "guard conditions" or "enable conditions," boolean predicates that authorize transitions in state machines or process synchronizations to resolve nondeterminism.[11] The term "guard" derives from the notion of "guarding" or protecting execution paths, a concept introduced by Edsger W. Dijkstra in his seminal work on guarded commands, where the boolean prefix safeguards the ensuing statements from invalid states.[2]Historical Development
Origins
The concept of guards in computer science originated with Edsger W. Dijkstra's development of the guarded command language (GCL) in 1975, as a key element of structured programming aimed at eliminating the use of goto statements for control flow.[2] In GCL, guards serve as boolean conditions prefixed to commands, enabling conditional execution in a disciplined manner that supports both deterministic and nondeterministic program behavior.[12] This innovation built on Dijkstra's earlier advocacy for structured programming, providing a formal alternative to unstructured branching while incorporating nondeterminism to handle choice points elegantly.[2] Dijkstra first formalized guards in his manuscript note EWD 472, titled "Guarded Commands, Nondeterminacy and Formal Derivation of Programs," circulated in spring 1975, which proposed them as building blocks for alternative (if-like) and repetitive (do-like) constructs.[12] The note introduced the notation where multiple guarded commands are combined using a nondeterministic choice operator (denoted as □), allowing the system to select any guard whose condition evaluates to true, or to abort if none do.[2] This publication, later appearing in the Communications of the ACM in August 1975, emphasized guards' role in deriving programs through stepwise refinement, ensuring correctness via predicate transformer semantics.[2] The initial purpose of guards was to provide a mathematically rigorous framework for modeling concurrency and parallelism, addressing the challenges of nondeterministic execution in multiprogramming systems without relying on low-level primitives like semaphores or unstructured jumps.[2] By replacing ad hoc control flows with guarded constructs, Dijkstra sought to tame the complexity of concurrent programs, enabling formal proofs of termination and correctness even under nondeterminism—termed "demonic" to reflect the adversarial selection of alternatives.[13] This approach contrasted with earlier deterministic languages, offering a way to express parallelism abstractly while avoiding race conditions through semantic guarantees.[2]Evolution
Following the initial formulation of guarded commands by Edsger Dijkstra in 1975, the concept expanded in the late 1970s and 1980s through integration into concurrent and parallel programming models. In 1978, Tony Hoare incorporated guarded commands into Communicating Sequential Processes (CSP), a formalism for describing interactions among concurrent processes, where guards enabled nondeterministic selection among alternatives based on boolean conditions and communication events. This adaptation extended guards beyond sequential control to synchronization in distributed systems. By 1983, the Ada programming language standardized guards in its tasking facilities, allowing conditional acceptance of entry calls in selective waits, which facilitated safe and efficient concurrent programming in real-time systems.[14] The 1990s marked a shift toward functional programming paradigms, where guards gained prominence for expressive conditional definitions. In Haskell, developed from 1987 and first released in 1990, guards were adopted as a core syntactic feature for function definitions, inspired by earlier languages like Miranda (1985), and placed on the left-hand side of equations to integrate seamlessly with pattern matching.[15] This design choice, finalized during Haskell's Yale design meeting in 1988, allowed guards to extend beyond imperative roots into declarative contexts. Later in the decade, monadic guards emerged via theguard function in the MonadPlus class, enabling filtered computations in monadic contexts like parsing and searching, further broadening their utility in pure functional settings.
During the 2000s and 2010s, guards proliferated in scripting and concurrent languages, emphasizing practical patterns for robustness. In Ruby, the guard clause pattern—early returns with conditional checks—became a recommended idiom for simplifying control flow and reducing nesting, as promoted in community style guides and tools like RuboCop starting around the mid-2000s.[16] Similarly, Erlang's receive expressions have long featured guards since the language's early implementations in the 1980s, but their role in selective message pattern matching saw wider adoption in the 2000s for building fault-tolerant distributed systems.
Up to 2025, guards have evolved in asynchronous and AI-assisted programming for enhanced safety and reliability. In JavaScript, proposals and framework extensions, such as async route guards in libraries like Vue.js, have incorporated guard-like mechanisms to validate conditions before proceeding in asynchronous flows, addressing error-prone promise chains. Meanwhile, AI-driven code generation tools, including GitHub Copilot and specialized frameworks like Project CodeGuard, increasingly incorporate guards and guardrails to mitigate vulnerabilities in generated code, ensuring conditional checks for security and correctness in automated development workflows.[17]
Applications
In Imperative Programming
In imperative programming, guards manifest primarily as conditional checks within if-else chains or switch statements that enable early termination of execution paths, thereby flattening complex nested structures into sequential logic. This approach, known as the guard clause pattern, involves placing preconditions at the function's entry point and returning immediately if they fail, allowing the main code to focus on the successful path without deep indentation. For instance, in Python, developers often use early returns as guards to validate inputs before proceeding, avoiding the need for nested if statements that obscure the primary logic.[5] The key benefit of this pattern lies in its ability to reduce code nesting, which minimizes indentation levels and enhances readability by isolating edge cases upfront. Consider a nested if-else structure in pseudocode for processing employee pay:if (!isDead) {
if (isSeparated) {
result = separatedAmount();
} else {
if (isRetired) {
result = retiredAmount();
} else {
result = normalPayAmount();
}
}
}
if (!isDead) {
if (isSeparated) {
result = separatedAmount();
} else {
if (isRetired) {
result = retiredAmount();
} else {
result = normalPayAmount();
}
}
}
if (isDead) return deadAmount();
if (isSeparated) return separatedAmount();
if (isRetired) return retiredAmount();
return normalPayAmount();
if (isDead) return deadAmount();
if (isSeparated) return separatedAmount();
if (isRetired) return retiredAmount();
return normalPayAmount();
wait() and notify() to suspend threads until a predicate holds true, preventing busy-waiting and race conditions; for example, a producer-consumer queue might guard on queue emptiness before consuming.[19]
This guard mechanism traces back to early imperative extensions and has evolved into modern error-handling paradigms, such as Rust's Result type introduced in its 1.0 stable release in 2015, which encodes success or failure outcomes and encourages guard-like pattern matching on errors to propagate or handle them explicitly without exceptions.[20]
In Functional Programming
In functional programming, guards originated in David Turner's KRC (Kent Recursive Calculator) in the early 1980s, and were later included in his Miranda language in the mid-1980s, where they served as conditional clauses attached to function equations to select among alternative right-hand sides based on boolean expressions.[21][15][22] This feature was adopted and refined in Haskell's initial report in 1990, positioning guards to the left of the equals sign for better alignment with pattern matching syntax.[15][3] A core application of guards appears in function definitions and case expressions, enabling concise conditional branching while preserving the declarative style of functional languages. In Haskell, for instance, guards follow a function's parameters and are prefixed by a pipe symbol, with each guard evaluating a boolean condition to determine if the associated expression should execute; the first true guard wins, orotherwise handles the default case.[3] Consider the absolute value function:
abs :: Num a => a -> a
abs x | x >= 0 = x
| otherwise = -x
abs :: Num a => a -> a
abs x | x >= 0 = x
| otherwise = -x
case value of
x | even x -> "Even"
| otherwise -> "Odd"
case value of
x | even x -> "Even"
| otherwise -> "Odd"
[x^2 | x <- [1..10], x > 5] generates squares only for values exceeding 5, desugaring to nested applications of map and filter for efficiency in lazy evaluation.[3] Scala, introduced in 2004, extends this to for-comprehensions, which generalize list comprehensions over collections and monads; guards appear as if clauses to filter yields, as in:
for (x <- 1 to 10 if x > 5) yield x * x
for (x <- 1 to 10 if x > 5) yield x * x
when clauses to add boolean constraints to patterns, supporting the language's functional subset.[24] For example:
match num with
| x when x > 0 -> "Positive"
| _ -> "Non-positive"
match num with
| x when x > 0 -> "Positive"
| _ -> "Non-positive"
Pattern Guards
Pattern guards represent a specialized form of conditional pattern matching where a guard expression is attached directly to a pattern in constructs like case statements or function definitions, allowing both structural matching and additional refinement through conditions. In this mechanism, the pattern first attempts to bind variables from the input data, and if successful, the associated guard—typically a boolean expression—evaluates using those bindings to determine if the match proceeds.[3] This integration fails if either the pattern does not match or the guard evaluates to false, enabling precise control over which branch of a multi-pattern construct is selected.[3] The functionality of pattern guards operates in two phases: initial pattern matching binds variables without side effects, followed by guard evaluation that can reference those bindings for tests like comparisons or type checks. For instance, in Haskell, the syntax permits guards like| pat <- exp, boolean_condition -> body, where pat matches the result of exp, binding variables for use in boolean_condition. If both succeed, the body executes; otherwise, the next alternative is tried. This sequential refinement ensures that complex data structures are deconstructed and validated concisely within a single clause.[3]
Pattern guards are prominent in several languages, particularly those emphasizing functional and logic paradigms. In Haskell, they were formalized in the Haskell 2010 language report, building on an earlier proposal, with syntax such as:
f x | Just y <- x, y > 0 -> y
| otherwise -> 0
f x | Just y <- x, y > 0 -> y
| otherwise -> 0
Just y extracts a value from a Maybe constructor, and the guard y > 0 further filters it, returning y only if positive.[3] In Erlang, pattern guards appear in receive expressions for message passing, where a clause like receive {Pid, Msg} when is_pid(Pid) -> Pid ! Msg end first matches the tuple pattern {Pid, Msg} against incoming messages and then applies the guard is_pid(Pid) to ensure Pid is a valid process identifier before forwarding Msg.[25]
This combination yields advantages in expressiveness, allowing developers to handle intricate data shapes—like nested lists or trees—with minimal boilerplate. For example, refining a list pattern such as (x:xs) | length xs > 1 -> ... in Haskell or Erlang matches a non-empty list and guards on its tail length, promoting readable code for scenarios involving structured data validation without nested conditionals. Such features reduce the need for auxiliary functions, enhancing maintainability in pattern-heavy domains like parsing or concurrent messaging.[26]
Mathematical Foundations
Formal Semantics
In formal semantics, guards are treated as predicates over program states, with the set of all such predicates forming a complete lattice ordered by logical implication.[27] The denotational semantics of a guarded statementif g then s can be expressed as the conjunction of the guard predicate and the denotation of the body, denoted , where $$ represents the predicate capturing the postconditions established by .[1] This formulation aligns with weakest precondition calculus, where the weakest precondition for a guarded command is given by , ensuring that the postcondition holds after execution only if the guard is true (with abort otherwise in GCL).[1]
From an operational perspective, the semantics of guards is defined through evaluation rules that model execution as partial functions over states, where a failed guard (evaluating to false) results in no state transition for that branch, effectively skipping to alternative options or aborting the construct if none available (non-termination in GCL if-statement). This partiality captures the conditional nature of guards without committing to undefined behavior on failure, allowing the overall command to proceed via other enabled paths if available.
In the context of guarded command languages (GCL), guards introduce non-determinism, enabling choices that can be formalized as angelic or demonic, where demonic choice requires all possible executions to satisfy the postcondition, modeled as relations over state pairs.[13] For a guarded choice construct, the semantics is the union of the relations from successful branches: , representing all possible final states reachable from an initial state via guards that hold and corresponding statements .[1]
Guarded Command Models
Guarded Command Language (GCL), introduced by Edsger W. Dijkstra, structures programs using commands of the form , where is a precondition (guard), is the statement body, and is a postcondition, ensuring that if holds before executing , then holds afterward.[2] In nondeterministic constructs, guards enable selection among alternatives, as in the if-statementif | g_1 → s_1 [] g_2 → s_2 [] ... [] g_n → s_n fi, where execution selects and performs an arbitrary for which is true, or aborts if no guard holds.[2] Similarly, the repetitive construct do | g_1 → s_1 [] ... [] g_n → s_n od repeats this selection until no guard is true, providing a foundation for modeling bounded nondeterminism in program derivation.[2]
Predicate transformer semantics, central to GCL, define the weakest precondition as the condition that must hold before statement to ensure postcondition after termination.[2] For a basic guarded command , this is given by , meaning that the guard must hold along with the precondition for the body to establish (with abort if false).[2] For the full alternative construct, , ensuring at least one guard enables progress and each enabled body preserves .[2] These transformers facilitate formal reasoning about partial and total correctness by propagating postconditions backward through the program structure.
In concurrent settings, GCL concepts extend to shared-state systems via the UNITY framework developed by K. Mani Chandy and Jayadev Misra in the 1980s, where programs consist of a finite set of atomic actions, each a guarded command that executes nondeterministically when holds, assuming mutual exclusion for atomicity. These guards model enabling conditions for transitions in distributed or parallel computations, with fairness assumptions ensuring eventual execution of enabled actions, thus supporting proofs of liveness in multiprocess environments.
GCL and its extensions support program verification, particularly total correctness, through guard-based invariants that maintain system properties across executions. For repetitive constructs, an invariant must hold initially, be preserved by each enabled body (), and ensure progress by implying that if holds and guards are true, a variant decreases, guaranteeing termination when no guards remain true. In UNITY, similar invariants prove safety (invariance under actions) and progress (leads-to properties via guard implications), enabling compositional verification of concurrent programs without interleaving details.
Advanced Concepts
Multiple Guards
In programming languages, multiple guards often appear in sequential constructs, where they are evaluated in a fixed order until a true condition is found, at which point the corresponding body or branch is executed. This chained evaluation avoids nested conditionals; for instance, a structure likeif g1 then (if g2 then s1 else s2) else s3 can be flattened into sequential guards g1 → s1 | g2 → s2 | otherwise → s3 in languages supporting this syntax. Such sequential guards promote readability by aligning conditions linearly, with evaluation proceeding top-to-bottom or left-to-right based on textual order.[28][29]
Parallel or non-deterministic evaluation of multiple guards occurs in constructs where all guards are assessed before selection, allowing for concurrent or adversarial choice among true branches. In Dijkstra's Guarded Command Language (GCL), the guarded if-statement evaluates all guards simultaneously; if multiple are true, the system nondeterministically selects one branch to execute, potentially leading to all true branches in repetitive constructs like guarded do. This model supports both executing all true branches in non-deterministic repetition or selecting the first true in deterministic implementations.[2][1]
Selection strategies for multiple guards vary between theoretical and practical paradigms. In formal semantics, demonic nondeterminism treats choice as adversarial, where an opponent selects the branch to maximize failure or worst-case outcomes, as in GCL's abstraction for refinement. Conversely, angelic nondeterminism assumes an optimistic resolver that chooses the best outcome to ensure success when possible, aiding specification and verification. In practice, languages like OCaml employ short-circuiting in guard expressions using logical operators (e.g., &&), evaluating subsequent conditions only if prior ones succeed, to optimize sequential multi-guard checks. For example, in Prolog, multiple goals in a rule body—functioning as sequential conditions after head unification—are evaluated left-to-right, with failure backtracking to alternative clauses in textual order.[13][30][29][31]
