Short-circuit evaluation: Difference between revisions

From Rosetta Code
Content added Content deleted
(→‎E: new example)
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(198 intermediate revisions by more than 100 users not shown)
Line 1: Line 1:
{{task}}
{{task|Programming language concepts}}
{{Control Structures}}
Assume functions a and b return boolean values, and further, the execution of function b takes considerable resources without side effects, <!--treating the printing as being for illustrative purposes only--> and is to be minimised.


Assume functions &nbsp; <code>a</code> &nbsp; and &nbsp; <code>b</code> &nbsp; return boolean values, &nbsp; and further, the execution of function &nbsp; <code>b</code> &nbsp; takes considerable resources without side effects, <!--treating the printing as being for illustrative purposes only--> and is to be minimized.
If we needed to compute:
x = a() and b()
Then it would be best to not compute the value of b() if the value of a() is computed as False, as the value of x can then only ever be False.


Similarly, if we needed to compute:
If we needed to compute the conjunction &nbsp; (<code>and</code>):
y = a() or b()
:::: <code> x = a() and b() </code>
Then it would be best to not compute the value of b() if the value of a() is computed as True, as the value of x can then only ever be True.


Then it would be best to not compute the value of &nbsp; <code>b()</code> &nbsp; if the value of &nbsp; <code>a()</code> &nbsp; is computed as &nbsp; <code>false</code>, &nbsp; as the value of &nbsp; <code>x</code> &nbsp; can then only ever be &nbsp; <code> false</code>.
Some languages will stop further computation of boolean equations as soon as the result is known, so-called short-circuit evaluation of boolean expressions


Similarly, if we needed to compute the disjunction (<code>or</code>):
'''Task Description'''<br>
:::: <code> y = a() or b() </code>
The task is to create two functions named a and b, that take and return the same boolean value. The functions should also print their name whenever they are called. Calculate and assign the values of the following equations to a variable in such a way that function b is only called when necessary:

x = a(i) and b(j)
Then it would be best to not compute the value of &nbsp; <code>b()</code> &nbsp; if the value of &nbsp; <code>a()</code> &nbsp; is computed as &nbsp; <code>true</code>, &nbsp; as the value of &nbsp; <code>y</code> &nbsp; can then only ever be &nbsp; <code>true</code>.
y = a(i) or b(j)

If the language does not have short-circuit evaluation, this might be achieved with nested if statements.
Some languages will stop further computation of boolean equations as soon as the result is known, so-called &nbsp; [[wp:Short-circuit evaluation|short-circuit evaluation]] &nbsp; of boolean expressions


;Task:
Create two functions named &nbsp; <code>a</code> &nbsp; and &nbsp; <code>b</code>, &nbsp; that take and return the same boolean value.

The functions should also print their name whenever they are called.

Calculate and assign the values of the following equations to a variable in such a way that function &nbsp; <code>b</code> &nbsp; is only called when necessary:
:::: <code> x = a(i) and b(j) </code>
:::: <code> y = a(i) or b(j) </code>

<br>If the language does not have short-circuit evaluation, this might be achieved with nested &nbsp; &nbsp; '''if''' &nbsp; &nbsp; statements.
<br><br>

=={{header|11l}}==
{{trans|Python}}

<syntaxhighlight lang="11l">F a(v)
print(‘ ## Called function a(#.)’.format(v))
R v

F b(v)
print(‘ ## Called function b(#.)’.format(v))
R v

L(i) (0B, 1B)
L(j) (0B, 1B)
print("\nCalculating: x = a(i) and b(j)")
V x = a(i) & b(j)
print(‘Calculating: y = a(i) or b(j)’)
V y = a(i) | b(j)</syntaxhighlight>

{{out}}
<pre>

Calculating: x = a(i) and b(j)
# Called function a(0B)
Calculating: y = a(i) or b(j)
# Called function a(0B)
# Called function b(0B)

Calculating: x = a(i) and b(j)
# Called function a(0B)
Calculating: y = a(i) or b(j)
# Called function a(0B)
# Called function b(1B)

Calculating: x = a(i) and b(j)
# Called function a(1B)
# Called function b(0B)
Calculating: y = a(i) or b(j)
# Called function a(1B)

Calculating: x = a(i) and b(j)
# Called function a(1B)
# Called function b(1B)
Calculating: y = a(i) or b(j)
# Called function a(1B)
</pre>


=={{header|6502 Assembly}}==
There are no built-in booleans but the functionality can be easily implemented with 0 = False and 255 = True.

Source Code for the module:
<syntaxhighlight lang="6502asm">;DEFINE 0 AS FALSE, $FF as true.
False equ 0
True equ 255
Func_A:
;input: accumulator = value to check. 0 = false, nonzero = true.
;output: 0 if false, 255 if true. Also prints the truth value to the screen.
;USAGE: LDA val JSR Func_A
BEQ .falsehood
load16 z_HL,BoolText_A_True ;lda #<BoolText_A_True sta z_L lda #>BoolText_A_True sta z_H
jsr PrintString
jsr NewLine
LDA #True
rts
.falsehood:
load16 z_HL,BoolText_A_False
jsr PrintString
jsr NewLine
LDA #False
rts
Func_B:
;input: Y = value to check. 0 = false, nonzero = true.
;output: 0 if false, 255 if true. Also prints the truth value to the screen.
;USAGE: LDY val JSR Func_B
TYA
BEQ .falsehood ;return false
load16 z_HL,BoolText_B_True
jsr PrintString
jsr NewLine
LDA #True
rts
.falsehood:
load16 z_HL,BoolText_B_False
jsr PrintString
jsr NewLine
LDA #False
rts


Func_A_and_B:
;input:
; z_B = input for Func_A
; z_C = input for Func_B
;output:
;0 if false, 255 if true
LDA z_B
jsr Func_A
BEQ .falsehood
LDY z_C
jsr Func_B
BEQ .falsehood
;true
load16 z_HL,BoolText_A_and_B_True
jsr PrintString
jsr NewLine
LDA #True
rts
.falsehood:
load16 z_HL,BoolText_A_and_B_False
jsr PrintString
jsr NewLine
LDA #False
rts
Func_A_or_B:
;input:
; z_B = input for Func_A
; z_C = input for Func_B
;output:
;0 if false, 255 if true
LDA z_B
jsr Func_A
BNE .truth
LDY z_C
jsr Func_B
BNE .truth
;false
load16 z_HL,BoolText_A_or_B_False
jsr PrintString
LDA #False
rts
.truth:
load16 z_HL,BoolText_A_or_B_True
jsr PrintString
LDA #True
rts
BoolText_A_True:
db "A IS TRUE",0
BoolText_A_False:
db "A IS FALSE",0
BoolText_B_True:
db "B IS TRUE",0
BoolText_B_False:
db "B IS FALSE",0
BoolText_A_and_B_True:
db "A AND B IS TRUE",0
BoolText_A_and_B_False:
db "A AND B IS FALSE",0
BoolText_A_or_B_True:
db "A OR B IS TRUE",0
BoolText_A_or_B_False:
db "A OR B IS FALSE",0</syntaxhighlight>


The relevant code for the actual invoking of the functions:
<syntaxhighlight lang="6502asm">lda #True
sta z_B
lda #True
sta z_C
jsr Func_A_and_B
jsr NewLine
jsr Func_A_or_B
jmp *</syntaxhighlight>

And finally the output:
[[https://i.ibb.co/TTJRphL/shortcircuit.png Output image]]

=={{header|Action!}}==
<syntaxhighlight lang="action!">BYTE FUNC a(BYTE x)
PrintF(" a(%B)",x)
RETURN (x)

BYTE FUNC b(BYTE x)
PrintF(" b(%B)",x)
RETURN (x)

PROC Main()
BYTE i,j

FOR i=0 TO 1
DO
FOR j=0 TO 1
DO
PrintF("Calculating %B AND %B: call",i,j)
IF a(i)=1 AND b(j)=1 THEN
FI
PutE()
OD
OD
PutE()

FOR i=0 TO 1
DO
FOR j=0 TO 1
DO
PrintF("Calculating %B OR %B: call",i,j)
IF a(i)=1 OR b(j)=1 THEN
FI
PutE()
OD
OD
RETURN</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Short-circuit_evaluation.png Screenshot from Atari 8-bit computer]
<pre>
Calculating 0 AND 0: call a(0)
Calculating 0 AND 1: call a(0)
Calculating 1 AND 0: call a(1) b(0)
Calculating 1 AND 1: call a(1) b(1)

Calculating 0 OR 0: call a(0) b(0)
Calculating 0 OR 1: call a(0) b(1)
Calculating 1 OR 0: call a(1)
Calculating 1 OR 1: call a(1)
</pre>


=={{header|Ada}}==
=={{header|Ada}}==
Ada has built-in short-circuit operations '''and then''' and '''or else''':
Ada has built-in short-circuit operations '''and then''' and '''or else''':
<syntaxhighlight lang="ada">with Ada.Text_IO; use Ada.Text_IO;
<lang Ada>
with Ada.Text_IO; use Ada.Text_IO;


procedure Test_Short_Circuit is
procedure Test_Short_Circuit is
Line 47: Line 281:
end loop;
end loop;
end loop;
end loop;
end Test_Short_Circuit;
end Test_Short_Circuit;</syntaxhighlight>
{{out|Sample output}}
</lang>
Sample output:
<pre>
<pre>
A=FALSE (A and then B)=FALSE
A=FALSE (A and then B)=FALSE
Line 64: Line 297:
===With Standard===
===With Standard===
{{works with|ALGOL 68|Revision 1 - no extensions to language used}}
{{works with|ALGOL 68|Revision 1 - no extensions to language used}}

{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-1.18.0/algol68g-1.18.0-9h.tiny.el5.centos.fc11.i386.rpm/download 1.18.0-9h.tiny]}}
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-1.18.0/algol68g-1.18.0-9h.tiny.el5.centos.fc11.i386.rpm/download 1.18.0-9h.tiny]}}

{{works with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d]}}
{{works with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d]}}

Note: The "brief" ''conditional clause'' ( ~ | ~ | ~ ) is a the standard's ''shorthand'' for enforcing ''short-circuit evaluation''. Moreover, the coder is able to define their own '''proc'''[edures] and '''op'''[erators] that implement ''short-circuit evaluation'' by using Algol68's ''proceduring''.
Note: The "brief" ''conditional clause'' ( ~ | ~ | ~ ) is a the standard's ''shorthand'' for enforcing ''short-circuit evaluation''. Moreover, the coder is able to define their own '''proc'''[edures] and '''op'''[erators] that implement ''short-circuit evaluation'' by using Algol68's ''proceduring''.
<lang algol68>PRIO ORELSE = 2, ANDTHEN = 3; # user defined operators #
<syntaxhighlight lang="algol68">PRIO ORELSE = 2, ANDTHEN = 3; # user defined operators #
OP ORELSE = (BOOL a, PROC BOOL b)BOOL: ( a | a | b ),
OP ORELSE = (BOOL a, PROC BOOL b)BOOL: ( a | a | b ),
ANDTHEN = (BOOL a, PROC BOOL b)BOOL: ( a | b | a );
ANDTHEN = (BOOL a, PROC BOOL b)BOOL: ( a | b | a );
Line 107: Line 337:
print(("T ANDTHEN T = ", a(TRUE) ANDTHEN (BOOL:b(TRUE)), new line))
print(("T ANDTHEN T = ", a(TRUE) ANDTHEN (BOOL:b(TRUE)), new line))


)</lang>
)</syntaxhighlight>
{{out}}
Output:
<pre>
<pre>
a=T, T ORELSE F = T
a=T, T ORELSE F = T
Line 122: Line 352:
===With Extensions===
===With Extensions===
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-1.18.0/algol68g-1.18.0-9h.tiny.el5.centos.fc11.i386.rpm/download 1.18.0-9h.tiny]}}
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-1.18.0/algol68g-1.18.0-9h.tiny.el5.centos.fc11.i386.rpm/download 1.18.0-9h.tiny]}}

{{works with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d]}}
{{works with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d]}}
<lang algol68>test:(
<syntaxhighlight lang="algol68">test:(


PROC a = (BOOL a)BOOL: ( print(("a=",a,", ")); a),
PROC a = (BOOL a)BOOL: ( print(("a=",a,", ")); a),
Line 148: Line 377:
END CO
END CO


)</lang>
)</syntaxhighlight>
{{out}}
Output:
<pre>
<pre>
a=T, T OREL F = T
a=T, T OREL F = T
Line 161: Line 390:
</pre>
</pre>


=={{header|E}}==
=={{header|ALGOL W}}==
In Algol W the boolean "and" and "or" operators are short circuit operators.
<syntaxhighlight lang="algolw">begin


logical procedure a( logical value v ) ; begin write( "a: ", v ); v end ;
E defines <code>&amp;&amp;</code> and <code>||</code> in the usual short-circuiting fashion.
logical procedure b( logical value v ) ; begin write( "b: ", v ); v end ;


write( "and: ", a( true ) and b( true ) );
<lang e>def a(v) { println("a"); return v }
write( "---" );
write( "or: ", a( true ) or b( true ) );
write( "---" );
write( "and: ", a( false ) and b( true ) );
write( "---" );
write( "or: ", a( false ) or b( true ) );
write( "---" );
end.</syntaxhighlight>
{{out}}
<pre>
and:
a: true
b: true true
---
or:
a: true true
---
and:
a: false false
---
or:
a: false
b: true true
---
</pre>

=={{header|AppleScript}}==

AppleScript's boolean operators are short-circuiting (as can be seen from the log below).

What AppleScript lacks, however, is a short-circuiting ternary operator like the '''e ? e2 : e3''' of C, or a short-circuiting three-argument function like '''cond''' in Lisp. To get a similar effect in AppleScript, we have to delay evaluation on both sides, using a '''cond''' which returns a reference to one of two unapplied handlers, and composing the result with a separate '''apply''' function, to apply the selected handler function to its argument.

(As a statement, rather than an expression, the ''if ... then ... else'' structure does not compose – unlike ''cond'' or ''? :'', it can not be nested inside expressions)

<syntaxhighlight lang="applescript">on run
map(test, {|and|, |or|})
end run

-- test :: ((Bool, Bool) -> Bool) -> (Bool, Bool, Bool, Bool)
on test(f)
map(f, {{true, true}, {true, false}, {false, true}, {false, false}})
end test



-- |and| :: (Bool, Bool) -> Bool
on |and|(tuple)
set {x, y} to tuple
a(x) and b(y)
end |and|

-- |or| :: (Bool, Bool) -> Bool
on |or|(tuple)
set {x, y} to tuple
a(x) or b(y)
end |or|

-- a :: Bool -> Bool
on a(bool)
log "a"
return bool
end a

-- b :: Bool -> Bool
on b(bool)
log "b"
return bool
end b


-- map :: (a -> b) -> [a] -> [b]
on map(f, xs)
script mf
property lambda : f
end script
set lng to length of xs
set lst to {}
repeat with i from 1 to lng
set end of lst to mf's lambda(item i of xs, i, xs)
end repeat
return lst
end map

</syntaxhighlight>


{{Out}}
<pre>Messages:
(*a*)
(*b*)
(*a*)
(*b*)
(*a*)
(*a*)
(*a*)
(*a*)
(*a*)
(*b*)
(*a*)
(*b*)
Result:
{{true, false, false, false}, {true, true, true, false}}
</pre>

=={{header|Arturo}}==

<syntaxhighlight lang="arturo">a: function [v][
print ["called function A with:" v]
v
]

b: function [v][
print ["called function B with:" v]
v
]

loop @[true false] 'i ->
loop @[true false] 'j ->
print ["\tThe result of A(i) AND B(j) is:" and? -> a i -> b j]

print ""

loop @[true false] 'i ->
loop @[true false] 'j ->
print ["\tThe result of A(i) OR B(j) is:" or? -> a i -> b j]</syntaxhighlight>

{{out}}

<pre>called function A with: true
called function B with: true
The result of A(i) AND B(j) is: true
called function A with: true
called function B with: false
The result of A(i) AND B(j) is: false
called function A with: false
The result of A(i) AND B(j) is: false
called function A with: false
The result of A(i) AND B(j) is: false

called function A with: true
The result of A(i) OR B(j) is: true
called function A with: true
The result of A(i) OR B(j) is: true
called function A with: false
called function B with: true
The result of A(i) OR B(j) is: true
called function A with: false
called function B with: false
The result of A(i) OR B(j) is: false</pre>

=={{header|AutoHotkey}}==
In AutoHotkey, the boolean operators, '''and''', '''or''', and ternaries, short-circuit:
<syntaxhighlight lang="autohotkey">i = 1
j = 1
x := a(i) and b(j)
y := a(i) or b(j)

a(p)
{
MsgBox, a() was called with the parameter "%p%".
Return, p
}

b(p)
{
MsgBox, b() was called with the parameter "%p%".
Return, p
}</syntaxhighlight>

=={{header|AWK}}==
Short-circuit evalation is done in logical AND (&&) and logical OR (||) operators:
<syntaxhighlight lang="awk">#!/usr/bin/awk -f
BEGIN {
print (a(1) && b(1))
print (a(1) || b(1))
print (a(0) && b(1))
print (a(0) || b(1))
}


function a(x) {
print " x:"x
return x
}
function b(y) {
print " y:"y
return y
}</syntaxhighlight>
{{out}}
<pre>
x:1
y:1
1
x:1
1
x:0
0
x:0
y:1
1
</pre>

=={{header|Axe}}==
<syntaxhighlight lang="axe">TEST(0,0)
TEST(0,1)
TEST(1,0)
TEST(1,1)
Return

Lbl TEST
r₁→X
r₂→Y
Disp X▶Hex+3," and ",Y▶Hex+3," = ",(A(X)?B(Y))▶Hex+3,i
Disp X▶Hex+3," or ",Y▶Hex+3," = ",(A(X)??B(Y))▶Hex+3,i
.Wait for keypress
getKeyʳ
Return

Lbl A
r₁
Return

Lbl B
r₁
Return</syntaxhighlight>

=={{header|BASIC}}==
==={{header|BaCon}}===
BaCon supports short-circuit evaluation.

<syntaxhighlight lang="freebasic">' Short-circuit evaluation
FUNCTION a(f)
PRINT "FUNCTION a"
RETURN f
END FUNCTION

FUNCTION b(f)
PRINT "FUNCTION b"
RETURN f
END FUNCTION

PRINT "FALSE and TRUE"
x = a(FALSE) AND b(TRUE)
PRINT x

PRINT "TRUE and TRUE"
x = a(TRUE) AND b(TRUE)
PRINT x

PRINT "FALSE or FALSE"
y = a(FALSE) OR b(FALSE)
PRINT y

PRINT "TRUE or FALSE"
y = a(TRUE) OR b(FALSE)
PRINT y</syntaxhighlight>

{{out}}
<pre>prompt$ ./short-circuit
FALSE and TRUE
FUNCTION a
0
TRUE and TRUE
FUNCTION a
FUNCTION b
1
FALSE or FALSE
FUNCTION a
FUNCTION b
0
TRUE or FALSE
FUNCTION a
1</pre>

=={{header|Batch File}}==
{{trans|Liberty BASIC}}
<syntaxhighlight lang="dos">%=== Batch Files have no booleans on if command, let alone short-circuit evaluation ===%
%=== I will instead use 1 as true and 0 as false. ===%

@echo off
setlocal enabledelayedexpansion
echo AND
for /l %%i in (0,1,1) do (
for /l %%j in (0,1,1) do (
echo.a^(%%i^) AND b^(%%j^)
call :a %%i
set res=!bool_a!
if not !res!==0 (
call :b %%j
set res=!bool_b!
)
echo.=^> !res!
)
)

echo ---------------------------------
echo OR
for /l %%i in (0,1,1) do (
for /l %%j in (0,1,1) do (
echo a^(%%i^) OR b^(%%j^)
call :a %%i
set res=!bool_a!
if !res!==0 (
call :b %%j
set res=!bool_b!
)
echo.=^> !res!
)
)
pause>nul
exit /b 0


::----------------------------------------
:a
echo. calls func a
set bool_a=%1
goto :EOF

:b
echo. calls func b
set bool_b=%1
goto :EOF</syntaxhighlight>
{{Out}}
<pre>AND
a(0) AND b(0)
calls func a
=> 0
a(0) AND b(1)
calls func a
=> 0
a(1) AND b(0)
calls func a
calls func b
=> 0
a(1) AND b(1)
calls func a
calls func b
=> 1
---------------------------------
OR
a(0) OR b(0)
calls func a
calls func b
=> 0
a(0) OR b(1)
calls func a
calls func b
=> 1
a(1) OR b(0)
calls func a
=> 1
a(1) OR b(1)
calls func a
=> 1
</pre>

=={{header|BBC BASIC}}==
Short-circuit operators aren't implemented directly, but short-circuit AND can be simulated using cascaded IFs. Short-circuit OR can be converted into a short-circuit AND using De Morgan's laws.
<syntaxhighlight lang="bbcbasic"> REM TRUE is represented as -1, FALSE as 0
FOR i% = TRUE TO FALSE
FOR j% = TRUE TO FALSE
PRINT "For x=a(";FNboolstring(i%);") AND b(";FNboolstring(j%);")"
x% = FALSE
REM Short-circuit AND can be simulated by cascaded IFs:
IF FNa(i%) IF FNb(j%) THEN x%=TRUE
PRINT "x is ";FNboolstring(x%)
PRINT
PRINT "For y=a(";FNboolstring(i%);") OR b(";FNboolstring(j%);")"
y% = FALSE
REM Short-circuit OR can be simulated by De Morgan's laws:
IF NOTFNa(i%) IF NOTFNb(j%) ELSE y%=TRUE : REM Note ELSE without THEN
PRINT "y is ";FNboolstring(y%)
PRINT
NEXT:NEXT
END
DEFFNa(bool%)
PRINT "Function A used; ";
=bool%
DEFFNb(bool%)
PRINT "Function B used; ";
=bool%
DEFFNboolstring(bool%)
IF bool%=0 THEN ="FALSE" ELSE="TRUE"</syntaxhighlight>
This gives the results shown below:
<pre>For x=a(TRUE) AND b(TRUE)
Function A used; Function B used; x is TRUE

For y=a(TRUE) OR b(TRUE)
Function A used; y is TRUE

For x=a(TRUE) AND b(FALSE)
Function A used; Function B used; x is FALSE

For y=a(TRUE) OR b(FALSE)
Function A used; y is TRUE

For x=a(FALSE) AND b(TRUE)
Function A used; x is FALSE

For y=a(FALSE) OR b(TRUE)
Function A used; Function B used; y is TRUE

For x=a(FALSE) AND b(FALSE)
Function A used; x is FALSE

For y=a(FALSE) OR b(FALSE)
Function A used; Function B used; y is FALSE
</pre>

=={{header|Bracmat}}==
Bracmat has no booleans. The closest thing is the success or failure of an expression. A function is not called if the argument fails, so we have to use a trick to pass 'failure' to a function. Here it is accomplished by an extra level of indirection: two == in the definition of 'false' (and 'true', for symmetry) and two !! when evaluating the argument in the functions a and b. The backtick is another hack. This prefix tells Bracmat to look the other way if the backticked expression fails and to continue as if the expression succeeded. A neater way is to introduce an extra OR operator. That solution would have obscured the core of the current task.
Short-circuit evaluation is heavily used in Bracmat code. Although not required, it is a good habit to exclusively use AND (&) and OR (|) operators to separate expressions, as the code below exemplifies.
<syntaxhighlight lang="bracmat">( (a=.out$"I'm a"&!!arg)
& (b=.out$"I'm b"&!!arg)
& (false==~)
& (true==)
& !false !true:?outer
& whl
' ( !outer:%?x ?outer
& !false !true:?inner
& whl
' ( !inner:%?y ?inner
& out
$ ( Testing
(!!x&true|false)
AND
(!!y&true|false)
)
& `(a$!x&b$!y)
& out
$ ( Testing
(!!x&true|false)
OR
(!!y&true|false)
)
& `(a$!x|b$!y)
)
)
& done
);
</syntaxhighlight>
Output:
<pre>Testing false AND false
I'm a
Testing false OR false
I'm a
I'm b
Testing false AND true
I'm a
Testing false OR true
I'm a
I'm b
Testing true AND false
I'm a
I'm b
Testing true OR false
I'm a
Testing true AND true
I'm a
I'm b
Testing true OR true
I'm a</pre>

=={{header|C}}==
Boolean operators <nowiki>&&</nowiki> and || are shortcircuit operators.
<syntaxhighlight lang="c">#include <stdio.h>
#include <stdbool.h>

bool a(bool in)
{
printf("I am a\n");
return in;
}

bool b(bool in)
{
printf("I am b\n");
return in;
}

#define TEST(X,Y,O) \
do { \
x = a(X) O b(Y); \
printf(#X " " #O " " #Y " = %s\n\n", x ? "true" : "false"); \
} while(false);

int main()
{
bool x;

TEST(false, true, &&); // b is not evaluated
TEST(true, false, ||); // b is not evaluated
TEST(true, false, &&); // b is evaluated
TEST(false, false, ||); // b is evaluated

return 0;
}</syntaxhighlight>

=={{header|C sharp|C#}}==
<syntaxhighlight lang="csharp">using System;

class Program
{
static bool a(bool value)
{
Console.WriteLine("a");
return value;
}

static bool b(bool value)
{
Console.WriteLine("b");
return value;
}

static void Main()
{
foreach (var i in new[] { false, true })
{
foreach (var j in new[] { false, true })
{
Console.WriteLine("{0} and {1} = {2}", i, j, a(i) && b(j));
Console.WriteLine();
Console.WriteLine("{0} or {1} = {2}", i, j, a(i) || b(j));
Console.WriteLine();
}
}
}
}</syntaxhighlight>
{{out}}
<syntaxhighlight lang="text">a
False and False = False

a
b
False or False = False

a
False and True = False

a
b
False or True = True

a
b
True and False = False

a
True or False = True

a
b
True and True = True

a
True or True = True</syntaxhighlight>

=={{header|C++}}==
Just like C, boolean operators <nowiki>&&</nowiki> and || are shortcircuit operators.
<syntaxhighlight lang="cpp">#include <iostream>

bool a(bool in)
{
std::cout << "a" << std::endl;
return in;
}

bool b(bool in)
{
std::cout << "b" << std::endl;
return in;
}

void test(bool i, bool j) {
std::cout << std::boolalpha << i << " and " << j << " = " << (a(i) && b(j)) << std::endl;
std::cout << std::boolalpha << i << " or " << j << " = " << (a(i) || b(j)) << std::endl;
}

int main()
{
test(false, false);
test(false, true);
test(true, false);
test(true, true);
return 0;
}</syntaxhighlight>
{{out}}
<pre>a
false and false = false
a
b
false or false = false
a
false and true = false
a
b
false or true = true
a
b
true and false = false
a
true or false = true
a
b
true and true = true
a
true or true = true</pre>

=={{header|Clojure}}==
The print/println stuff in the doseq is kinda gross, but if you include them all in a single print, then the function traces are printed before the rest (since it has to evaluate them before calling print).
<syntaxhighlight lang="clojure">(letfn [(a [bool] (print "(a)") bool)
(b [bool] (print "(b)") bool)]
(doseq [i [true false] j [true false]]
(print i "OR" j "= ")
(println (or (a i) (b j)))
(print i "AND" j " = ")
(println (and (a i) (b j)))))</syntaxhighlight>
{{out}}
<pre>true OR true = (a)true
true AND true = (a)(b)true
true OR false = (a)true
true AND false = (a)(b)false
false OR true = (a)(b)true
false AND true = (a)false
false OR false = (a)(b)false
false AND false = (a)false</pre>

=={{header|Common Lisp}}==
<syntaxhighlight lang="lisp">(defun a (F)
(print 'a)
F )

(defun b (F)
(print 'b)
F )

(dolist (x '((nil nil) (nil T) (T T) (T nil)))
(format t "~%(and ~S)" x)
(and (a (car x)) (b (car(cdr x))))
(format t "~%(or ~S)" x)
(or (a (car x)) (b (car(cdr x)))))</syntaxhighlight>
{{out}}
(and (NIL NIL))
A
(or (NIL NIL))
A
B
(and (NIL T))
A
(or (NIL T))
A
B
(and (T T))
A
B
(or (T T))
A
(and (T NIL))
A
B
(or (T NIL))
A

=={{header|D}}==
{{trans|Python}}
<syntaxhighlight lang="d">import std.stdio, std.algorithm;

T a(T)(T answer) {
writefln(" # Called function a(%s) -> %s", answer, answer);
return answer;
}

T b(T)(T answer) {
writefln(" # Called function b(%s) -> %s", answer, answer);
return answer;
}

void main() {
foreach (immutable x, immutable y;
[false, true].cartesianProduct([false, true])) {
writeln("\nCalculating: r1 = a(x) && b(y)");
immutable r1 = a(x) && b(y);
writeln("Calculating: r2 = a(x) || b(y)");
immutable r2 = a(x) || b(y);
}
}</syntaxhighlight>
{{out}}
<pre>
Calculating: r1 = a(x) && b(y)
# Called function a(false) -> false
Calculating: r2 = a(x) || b(y)
# Called function a(false) -> false
# Called function b(false) -> false

Calculating: r1 = a(x) && b(y)
# Called function a(true) -> true
# Called function b(false) -> false
Calculating: r2 = a(x) || b(y)
# Called function a(true) -> true

Calculating: r1 = a(x) && b(y)
# Called function a(false) -> false
Calculating: r2 = a(x) || b(y)
# Called function a(false) -> false
# Called function b(true) -> true

Calculating: r1 = a(x) && b(y)
# Called function a(true) -> true
# Called function b(true) -> true
Calculating: r2 = a(x) || b(y)
# Called function a(true) -> true</pre>

=={{header|Delphi}}==
Delphi supports short circuit evaluation by default. It can be turned off using the {$BOOLEVAL OFF} compiler directive.
<syntaxhighlight lang="delphi">program ShortCircuitEvaluation;

{$APPTYPE CONSOLE}

uses SysUtils;

function A(aValue: Boolean): Boolean;
begin
Writeln('a');
Result := aValue;
end;

function B(aValue: Boolean): Boolean;
begin
Writeln('b');
Result := aValue;
end;

var
i, j: Boolean;
begin
for i in [False, True] do
begin
for j in [False, True] do
begin
Writeln(Format('%s and %s = %s', [BoolToStr(i, True), BoolToStr(j, True), BoolToStr(A(i) and B(j), True)]));
Writeln;
Writeln(Format('%s or %s = %s', [BoolToStr(i, True), BoolToStr(j, True), BoolToStr(A(i) or B(j), True)]));
Writeln;
end;
end;
end.</syntaxhighlight>

=={{header|Dyalect}}==

{{trans|Swift}}

<syntaxhighlight lang="dyalect">func a(v) {
print(nameof(a), terminator: "")
return v
}
func b(v) {
print(nameof(b), terminator: "")
return v
}
func testMe(i, j) {
print("Testing a(\(i)) && b(\(j))")
print("Trace: ", terminator: "")
print("\nResult: \(a(i) && b(j))")
print("Testing a(\(i)) || b(\(j))")
print("Trace: ", terminator: "")
print("\nResult: \(a(i) || b(j))")
print()
}
testMe(false, false)
testMe(false, true)
testMe(true, false)
testMe(true, true)</syntaxhighlight>

{{out}}

<pre>Testing a(false) && b(false)
Trace: a
Result: false
Testing a(false) || b(false)
Trace: ab
Result: false

Testing a(false) && b(true)
Trace: a
Result: false
Testing a(false) || b(true)
Trace: ab
Result: true

Testing a(true) && b(false)
Trace: ab
Result: false
Testing a(true) || b(false)
Trace: a
Result: true

Testing a(true) && b(true)
Trace: ab
Result: true
Testing a(true) || b(true)
Trace: a
Result: true</pre>

=={{header|E}}==
E defines <code>&amp;&amp;</code> and <code>||</code> in the usual short-circuiting fashion.
<syntaxhighlight lang="e">def a(v) { println("a"); return v }
def b(v) { println("b"); return v }
def b(v) { println("b"); return v }


def x := a(i) && b(j)
def x := a(i) && b(j)
def y := b(i) || b(j)</lang>
def y := b(i) || b(j)</syntaxhighlight>

Unusually, E is an expression-oriented language, and variable bindings (which are expressions) are in scope until the end of the nearest enclosing <code>{ ... }</code> block. The combination of these features means that some semantics must be given to a binding occurring inside of a short-circuited alternative.
Unusually, E is an expression-oriented language, and variable bindings (which are expressions) are in scope until the end of the nearest enclosing <code>{ ... }</code> block. The combination of these features means that some semantics must be given to a binding occurring inside of a short-circuited alternative.
<syntaxhighlight lang="e">def x := a(i) && (def funky := b(j))</syntaxhighlight>
The choice we make is that <code>funky</code> is ordinary if the right-side expression was evaluated, and otherwise is <em>ruined</em>; attempts to access the variable give an error.


=={{header|EasyLang}}==
<lang e>def x := a(i) && (def funky := b(j))</lang>
<syntaxhighlight lang=easylang>
func a x .
print "->a: " & x
return x
.
func b x .
print "->b: " & x
return x
.
print "1 and 1"
if a 1 = 1 and b 1 = 1
print "-> true"
.
print ""
print "1 or 1"
if a 1 = 1 or b 1 = 1
print "-> true"
.
print ""
print "0 and 1"
if a 0 = 1 and b 1 = 1
print "-> true"
.
print ""
print "0 or 1"
if a 0 = 1 or b 1 = 1
print "-> true"
.
</syntaxhighlight>


=={{header|Ecstasy}}==
The choice we make is that <code>funky</code> is ordinary if the right-side expression was evaluated, and otherwise is <em>ruined</em>; attempts to access the variable give an error.
Similar to Java, Ecstasy uses the <span style="background-color: #e5e4e2">&nbsp;&amp;&amp;&nbsp;</tt></span> and <span style="background-color: #e5e4e2"><tt>&nbsp;||&nbsp;</tt></span> operators for short-circuiting logic, and <span style="background-color: #e5e4e2"><tt>&nbsp;&amp;&nbsp;</tt></span> and <span style="background-color: #e5e4e2"><tt>&nbsp;|&nbsp;</tt></span> are the normal (non-short-circuiting) forms.


<syntaxhighlight lang="java">
== Icon and Unicon ==
module test {
@Inject Console console;

static Boolean show(String name, Boolean value) {
console.print($"{name}()={value}");
return value;
}

void run() {
val a = show("a", _);
val b = show("b", _);

for (Boolean v1 : False..True) {
for (Boolean v2 : False..True) {
console.print($"a({v1}) && b({v2}) == {a(v1) && b(v2)}");
console.print();
console.print($"a({v1}) || b({v2}) == {a(v1) || b(v2)}");
console.print();
}
}
}
}
</syntaxhighlight>

{{out}}
<pre>
a()=False
a(False) && b(False) == False

a()=False
b()=False
a(False) || b(False) == False

a()=False
a(False) && b(True) == False

a()=False
b()=True
a(False) || b(True) == True

a()=True
b()=False
a(True) && b(False) == False

a()=True
a(True) || b(False) == True

a()=True
b()=True
a(True) && b(True) == True

a()=True
a(True) || b(True) == True
</pre>

=={{header|Elena}}==
ELENA 6.x :
<syntaxhighlight lang="elena">import system'routines;
import extensions;
Func<bool, bool> a = (bool x){ console.writeLine("a"); ^ x };
Func<bool, bool> b = (bool x){ console.writeLine("b"); ^ x };
const bool[] boolValues = new bool[]{ false, true };
public program()
{
boolValues.forEach::(bool i)
{
boolValues.forEach::(bool j)
{
console.printLine(i," and ",j," = ",a(i) && b(j));
console.writeLine();
console.printLine(i," or ",j," = ",a(i) || b(j));
console.writeLine()
}
}
}</syntaxhighlight>
{{out}}
<pre>
a
false and false = false

a
b
false or false = false

a
false and true = false

a
b
false or true = true

a
b
true and false = false

a
true or false = true

a
b
true and true = true

a
true or true = true
</pre>

=={{header|Elixir}}==
<syntaxhighlight lang="elixir">defmodule Short_circuit do
defp a(bool) do
IO.puts "a( #{bool} ) called"
bool
end
defp b(bool) do
IO.puts "b( #{bool} ) called"
bool
end
def task do
Enum.each([true, false], fn i ->
Enum.each([true, false], fn j ->
IO.puts "a( #{i} ) and b( #{j} ) is #{a(i) and b(j)}.\n"
IO.puts "a( #{i} ) or b( #{j} ) is #{a(i) or b(j)}.\n"
end)
end)
end
end

Short_circuit.task</syntaxhighlight>

{{out}}
<pre>
a( true ) called
b( true ) called
a( true ) and b( true ) is true.

a( true ) called
a( true ) or b( true ) is true.

a( true ) called
b( false ) called
a( true ) and b( false ) is false.

a( true ) called
a( true ) or b( false ) is true.

a( false ) called
a( false ) and b( true ) is false.

a( false ) called
b( true ) called
a( false ) or b( true ) is true.

a( false ) called
a( false ) and b( false ) is false.

a( false ) called
b( false ) called
a( false ) or b( false ) is false.
</pre>

=={{header|Erlang}}==
<syntaxhighlight lang="erlang">
-module( short_circuit_evaluation ).

-export( [task/0] ).

task() ->
[task_helper(X, Y) || X <- [true, false], Y <- [true, false]].



a( Boolean ) ->
io:fwrite( " a ~p~n", [Boolean] ),
Boolean.

b( Boolean ) ->
io:fwrite( " b ~p~n", [Boolean] ),
Boolean.

task_helper( Boolean1, Boolean2 ) ->
io:fwrite( "~p andalso ~p~n", [Boolean1, Boolean2] ),
io:fwrite( "=> ~p~n", [a(Boolean1) andalso b(Boolean2)] ),
io:fwrite( "~p orelse ~p~n", [Boolean1, Boolean2] ),
io:fwrite( "=> ~p~n", [a(Boolean1) orelse b(Boolean2)] ).
</syntaxhighlight>
{{out}}
<pre>
15> short_circuit_evaluation:task().
true andalso true
a true
b true
=> true
true orelse true
a true
=> true
true andalso false
a true
b false
=> false
true orelse false
a true
=> true
false andalso true
a false
=> false
false orelse true
a false
b true
=> true
false andalso false
a false
=> false
false orelse false
a false
b false
=> false
</pre>

=={{header|F_Sharp|F#}}==
<syntaxhighlight lang="fsharp">let a (x : bool) = printf "(a)"; x
let b (x : bool) = printf "(b)"; x

[for x in [true; false] do for y in [true; false] do yield (x, y)]
|> List.iter (fun (x, y) ->
printfn "%b AND %b = %b" x y ((a x) && (b y))
printfn "%b OR %b = %b" x y ((a x) || (b y)))</syntaxhighlight>
Output
<pre>(a)(b)true AND true = true
(a)true OR true = true
(a)(b)true AND false = false
(a)true OR false = true
(a)false AND true = false
(a)(b)false OR true = true
(a)false AND false = false
(a)(b)false OR false = false</pre>

=={{header|Factor}}==
<code>&&</code> and <code>||</code> perform short-circuit evaluation, while <code>and</code> and <code>or</code> do not. <code>&&</code> and <code>||</code> both expect a sequence of quotations to evaluate in a short-circuit manner. They are smart combinators; that is, they infer the number of arguments taken by the quotations. If you opt not to use the smart combinators, you can also use words like <code>0&&</code> and <code>2||</code> where the arity of the quotations is dictated.
<syntaxhighlight lang="factor">USING: combinators.short-circuit.smart io prettyprint ;
IN: rosetta-code.short-circuit

: a ( ? -- ? ) "(a)" write ;
: b ( ? -- ? ) "(b)" write ;

"f && f = " write { [ f a ] [ f b ] } && .
"f || f = " write { [ f a ] [ f b ] } || .
"f && t = " write { [ f a ] [ t b ] } && .
"f || t = " write { [ f a ] [ t b ] } || .
"t && f = " write { [ t a ] [ f b ] } && .
"t || f = " write { [ t a ] [ f b ] } || .
"t && t = " write { [ t a ] [ t b ] } && .
"t || t = " write { [ t a ] [ t b ] } || .</syntaxhighlight>
{{out}}
<pre>
f && f = (a)f
f || f = (a)(b)f
f && t = (a)f
f || t = (a)(b)t
t && f = (a)(b)f
t || f = (a)t
t && t = (a)(b)t
t || t = (a)t
</pre>

=={{header|Fantom}}==
<syntaxhighlight lang="fantom">class Main
{
static Bool a (Bool value)
{
echo ("in a")
return value
}

static Bool b (Bool value)
{
echo ("in b")
return value
}

public static Void main ()
{
[false,true].each |i|
{
[false,true].each |j|
{
Bool result := a(i) && b(j)
echo ("a($i) && b($j): " + result)
result = a(i) || b(j)
echo ("a($i) || b($j): " + result)
}
}
}
}</syntaxhighlight>
{{out}}
<pre>
in a
a(false) && b(false): false
in a
in b
a(false) || b(false): false
in a
a(false) && b(true): false
in a
in b
a(false) || b(true): true
in a
in b
a(true) && b(false): false
in a
a(true) || b(false): true
in a
in b
a(true) && b(true): true
in a
a(true) || b(true): true
</pre>

=={{header|Forth}}==
<syntaxhighlight lang="forth">\ Short-circuit evaluation definitions from Wil Baden, with minor name changes
: ENDIF postpone THEN ; immediate

: COND 0 ; immediate
: ENDIFS BEGIN DUP WHILE postpone ENDIF REPEAT DROP ; immediate
: ORELSE s" ?DUP 0= IF" evaluate ; immediate
: ANDIF s" DUP IF DROP" evaluate ; immediate
: .bool IF ." true " ELSE ." false " THEN ;
: A ." A=" DUP .bool ;
: B ." B=" DUP .bool ;
: test
CR
1 -1 DO 1 -1 DO
COND I A ANDIF J B ENDIFS ." ANDIF=" .bool CR
COND I A ORELSE J B ENDIFS ." ORELSE=" .bool CR
LOOP LOOP ;

\ An alternative based on explicitly short-circuiting conditionals, Dave Keenan
: END-PRIOR-IF 1 CS-ROLL postpone ENDIF ; immediate

: test
CR
1 -1 DO 1 -1 DO
I A IF J B IF 1 ELSE END-PRIOR-IF 0 ENDIF ." ANDIF=" .bool CR
I A 0= IF J B IF END-PRIOR-IF 1 ELSE 0 ENDIF ." ORELSE=" .bool CR
LOOP LOOP ;</syntaxhighlight>
{{out}}
<pre>A=true B=true ANDIF=true
A=true ORELSE=true
A=false ANDIF=false
A=false B=true ORELSE=true
A=true B=false ANDIF=false
A=true ORELSE=true
A=false ANDIF=false
A=false B=false ORELSE=false</pre>

=={{header|Fortran}}==
{{works with|Fortran|90 and later}}
Using an <code>IF .. THEN .. ELSE</code> construct
<syntaxhighlight lang="fortran">program Short_Circuit_Eval
implicit none

logical :: x, y
logical, dimension(2) :: l = (/ .false., .true. /)
integer :: i, j

do i = 1, 2
do j = 1, 2
write(*, "(a,l1,a,l1,a)") "Calculating x = a(", l(i), ") and b(", l(j), ")"
! a AND b
x = a(l(i))
if(x) then
x = b(l(j))
write(*, "(a,l1)") "x = ", x
else
write(*, "(a,l1)") "x = ", x
end if
write(*,*)
write(*, "(a,l1,a,l1,a)") "Calculating y = a(", l(i), ") or b(", l(j), ")"
! a OR b
y = a(l(i))
if(y) then
write(*, "(a,l1)") "y = ", y
else
y = b(l(j))
write(*, "(a,l1)") "y = ", y
end if
write(*,*)
end do
end do

contains

function a(value)
logical :: a
logical, intent(in) :: value

a = value
write(*, "(a,l1,a)") "Called function a(", value, ")"
end function

function b(value)
logical :: b
logical, intent(in) :: value
b = value
write(*, "(a,l1,a)") "Called function b(", value, ")"
end function
end program</syntaxhighlight>
{{out}}
<pre>Calculating x = a(F) and b(F)
Called function a(F)
x = F
Calculating y = a(F) or b(F)
Called function a(F)
Called function b(F)
y = F
Calculating x = a(F) and b(T)
Called function a(F)
x = F
Calculating y = a(F) or b(T)
Called function a(F)
Called function b(T)
y = T
Calculating x = a(T) and b(F)
Called function a(T)
Called function b(F)
x = F
Calculating y = a(T) or b(F)
Called function a(T)
y = T
Calculating x = a(T) and b(T)
Called function a(T)
Called function b(T)
x = T
Calculating y = a(T) or b(T)
Called function a(T)
y = T</pre>

=={{header|FreeBASIC}}==
<syntaxhighlight lang="freebasic">' FB 1.05.0 Win64

Function a(p As Boolean) As Boolean
Print "a() called"
Return p
End Function

Function b(p As Boolean) As Boolean
Print "b() called"
Return p
End Function

Dim As Boolean i, j, x, y
i = False
j = True
Print "Without short-circuit evaluation :"
Print
x = a(i) And b(j)
y = a(i) Or b(j)
Print "x = "; x; " y = "; y
Print
Print "With short-circuit evaluation :"
Print
x = a(i) AndAlso b(j) '' b(j) not called as a(i) = false and so x must be false
y = a(i) OrElse b(j) '' b(j) still called as can't determine y unless it is
Print "x = "; x; " y = "; y
Print
Print "Press any key to quit"
Sleep</syntaxhighlight>

{{out}}
<pre>
Without short-circuit evaluation :

a() called
b() called
a() called
b() called
x = false y = true

With short-circuit evaluation :

a() called
a() called
b() called
x = false y = true
</pre>

=={{header|Fōrmulæ}}==

{{FormulaeEntry|page=https://formulae.org/?script=examples/Short-circuit_evaluation}}

'''Solution'''

[[File:Fōrmulæ - Short-circuit evaluation 01.png]]

[[File:Fōrmulæ - Short-circuit evaluation 02.png]]

=={{header|Go}}==
Short circuit operators are <nowiki>&&</nowiki> and ||.
<syntaxhighlight lang="go">package main

import "fmt"

func a(v bool) bool {
fmt.Print("a")
return v
}

func b(v bool) bool {
fmt.Print("b")
return v
}

func test(i, j bool) {
fmt.Printf("Testing a(%t) && b(%t)\n", i, j)
fmt.Print("Trace: ")
fmt.Println("\nResult:", a(i) && b(j))

fmt.Printf("Testing a(%t) || b(%t)\n", i, j)
fmt.Print("Trace: ")
fmt.Println("\nResult:", a(i) || b(j))

fmt.Println("")
}

func main() {
test(false, false)
test(false, true)
test(true, false)
test(true, true)
}</syntaxhighlight>
{{out}}
<pre>Testing a(false) && b(false)
Trace: a
Result: false
Testing a(false) || b(false)
Trace: ab
Result: false

Testing a(false) && b(true)
Trace: a
Result: false
Testing a(false) || b(true)
Trace: ab
Result: true

Testing a(true) && b(false)
Trace: ab
Result: false
Testing a(true) || b(false)
Trace: a
Result: true

Testing a(true) && b(true)
Trace: ab
Result: true
Testing a(true) || b(true)
Trace: a
Result: true</pre>

=={{header|Groovy}}==
Like all C-based languages (of which I am aware), Groovy short-circuits the logical and (<nowiki>&&</nowiki>) and logical or (||) operations, but not the bitwise and (<nowiki>&</nowiki>) and bitwise or (|) operations.
<syntaxhighlight lang="groovy">def f = { println ' AHA!'; it instanceof String }
def g = { printf ('%5d ', it); it > 50 }

println 'bitwise'
assert g(100) & f('sss')
assert g(2) | f('sss')
assert ! (g(1) & f('sss'))
assert g(200) | f('sss')

println '''
logical'''
assert g(100) && f('sss')
assert g(2) || f('sss')
assert ! (g(1) && f('sss'))
assert g(200) || f('sss')</syntaxhighlight>
{{out}}
<pre>bitwise
100 AHA!
2 AHA!
1 AHA!
200 AHA!

logical
100 AHA!
2 AHA!
1 200</pre>

=={{header|Haskell}}==
[[Lazy evaluation]] makes it possible for user-defined functions to be short-circuited. An expression will not be evaluated as long as it is not [[pattern matching|pattern matched]]:
<syntaxhighlight lang="haskell">module ShortCircuit where

import Prelude hiding ((&&), (||))
import Debug.Trace

False && _ = False
True && False = False
_ && _ = True

True || _ = True
False || True = True
_ || _ = False

a p = trace ("<a " ++ show p ++ ">") p
b p = trace ("<b " ++ show p ++ ">") p

main = mapM_ print ( [ a p || b q | p <- [False, True], q <- [False, True] ]
++ [ a p && b q | p <- [False, True], q <- [False, True] ])</syntaxhighlight>
{{out}}
<pre>
<a False>
<b False>
False
<a False>
<b True>
True
<a True>
True
<a True>
True
<a False>
False
<a False>
False
<a True>
<b False>
False
<a True>
<b True>
True
</pre>
One can force the right-hand arguemnt to be evaluated first be using the alternate definitions:
<syntaxhighlight lang="haskell">_ && False = False
False && True = False
_ && _ = True

_ || True = True
True || False = True
_ || _ = False</syntaxhighlight>
{{out}}
<pre>
<b False>
<a False>
False
<b True>
True
<b False>
<a True>
True
<b True>
True
<b False>
False
<b True>
<a False>
False
<b False>
False
<b True>
<a True>
True
</pre>
The order of evaluation (in this case the original order again) can be seen in a more explicit form by [[syntactic sugar|desugaring]] the pattern matching:
<syntaxhighlight lang="haskell">p && q = case p of
False -> False
_ -> case q of
False -> False
_ -> True
p || q = case p of
True -> True
_ -> case q of
True -> True
_ -> False</syntaxhighlight>


=={{header|Icon}} and {{header|Unicon}}==
The entire concept of using 'boolean' values for logic control runs counter to the philosophy of Icon. Instead Icon has success (something that returns a result) and failure which is really a signal. The concept is similar to that used in [[:Category:SNOBOL4|SNOBOL4]] and [[:Category:Lisp|Lisp]] and far more potent than passing around and testing booleans. There is no way to pass around a 'false' value in that sense. Icon does have facilities for dealing with bits inside integers but these would not normally be used for control purposes. Because failure is a signal control is always evaluated in a short-circuit manner. One consequence of this is that an expression "i < j" doesn't return a boolean value, instead it returns the value of j. While this may seem odd at first it allows for elegant expressions like "i < j < k". Another benefit is that there is no need for programmers to devote effort to staying inside the bounds of any data type. For instance, if you loop and iterate beyond bounds the expression simply fails and the loop ends.
The entire concept of using 'boolean' values for logic control runs counter to the philosophy of Icon. Instead Icon has success (something that returns a result) and failure which is really a signal. The concept is similar to that used in [[:Category:SNOBOL4|SNOBOL4]] and [[:Category:Lisp|Lisp]] and far more potent than passing around and testing booleans. There is no way to pass around a 'false' value in that sense. Icon does have facilities for dealing with bits inside integers but these would not normally be used for control purposes. Because failure is a signal control is always evaluated in a short-circuit manner. One consequence of this is that an expression "i < j" doesn't return a boolean value, instead it returns the value of j. While this may seem odd at first it allows for elegant expressions like "i < j < k". Another benefit is that there is no need for programmers to devote effort to staying inside the bounds of any data type. For instance, if you loop and iterate beyond bounds the expression simply fails and the loop ends.


Line 187: Line 1,962:
* Rather than have the tasks print their own name, we will just utilize built-in tracing which will be more informative.
* Rather than have the tasks print their own name, we will just utilize built-in tracing which will be more informative.
This use of procedures as values is somewhat contrived but serves us well for demonstration purposes. In practice this approach would be strained since failure results aren't re-captured as values (and can't easily be).
This use of procedures as values is somewhat contrived but serves us well for demonstration purposes. In practice this approach would be strained since failure results aren't re-captured as values (and can't easily be).
<syntaxhighlight lang="icon">procedure main()
==={{header|Icon}}===
<lang Icon>procedure main()
&trace := -1 # ensures functions print their names
&trace := -1 # ensures functions print their names


Line 206: Line 1,980:
procedure false() #: fails always
procedure false() #: fails always
fail # for clarity but not needed as running into end has the same effect
fail # for clarity but not needed as running into end has the same effect
end</syntaxhighlight>
end
</lang>
Sample output for a single case:<pre>i,j := procedure true, procedure false
Sample output for a single case:<pre>i,j := procedure true, procedure false
i & j:
i & j:
Line 219: Line 1,992:
i,j := procedure true, procedure true</pre>
i,j := procedure true, procedure true</pre>


==={{header|Unicon}}===
=={{header|Insitux}}==
{{trans|Clojure}}
The Icon solution works in Unicon.
<syntaxhighlight lang="insitux">
(let a (fn (print-str "a ") %)
b (fn (print-str "b ") %)
f (pad-right " " 6))


(for i [true false] j [true false]
=={{header|J}}==
(print-str (f i) "OR " (f j) " = ")
(print (or (a i) (b j)))
(print-str (f i) "AND " (f j) " = ")
(print (and (a i) (b j))))
</syntaxhighlight>
{{out}}
<pre>
true OR true = a true
true AND true = a b true
true OR false = a true
true AND false = a b false
false OR true = a b true
false AND true = a false
false OR false = a b false
false AND false = a false
</pre>


=={{header|Io}}==
See the J wiki entry on [[j:Essays/Short Circuit Boolean|short circuit booleans]].
{{trans|Ruby}}
<syntaxhighlight lang="io">a := method(bool,
writeln("a(#{bool}) called." interpolate)
bool
)
b := method(bool,
writeln("b(#{bool}) called." interpolate)
bool
)


list(true,false) foreach(avalue,
<lang j>labeled=:1 :'[ smoutput@,&":~&m'
list(true,false) foreach(bvalue,
x := a(avalue) and b(bvalue)
writeln("x = a(#{avalue}) and b(#{bvalue}) is #{x}" interpolate)
writeln
y := a(avalue) or b(bvalue)
writeln("y = a(#{avalue}) or b(#{bvalue}) is #{y}" interpolate)
writeln
)
)</syntaxhighlight>
{{output}}
<pre>a(true) called.
b(true) called.
x = a(true) and b(true) is true

a(true) called.
y = a(true) or b(true) is true

a(true) called.
b(false) called.
x = a(true) and b(false) is false

a(true) called.
y = a(true) or b(false) is true

a(false) called.
x = a(false) and b(true) is false

a(false) called.
b(true) called.
y = a(false) or b(true) is true

a(false) called.
x = a(false) and b(false) is false

a(false) called.
b(false) called.
y = a(false) or b(false) is false</pre>

=={{header|J}}==
See the J wiki entry on [[j:Essays/Short Circuit Boolean|short circuit booleans]].
<syntaxhighlight lang="j">labeled=:1 :'[ smoutput@,&":~&m'
A=: 'A ' labeled
A=: 'A ' labeled
B=: 'B ' labeled
B=: 'B ' labeled
and=: ^:
and=: ^:
or=: 2 :'u^:(-.@v)'</lang>
or=: 2 :'u^:(-.@v)'</syntaxhighlight>
{{out|Example}}

<syntaxhighlight lang="j"> (A and B) 1
Example:

<lang> (A and B) 1
B 1
B 1
A 1
A 1
Line 247: Line 2,088:
B 0
B 0
A 0
A 0
0</lang>
0</syntaxhighlight>

Note that J evaluates right-to-left.
Note that J evaluates right-to-left.


Note also that both functions take the same argument (which might make this less than ideal for some purposes, but trying micromanage flow of control is usually counter-productive in J in much the way that global values can be counter-productive in an object oriented environment. When you are processing a large set of array data, flow of control can only make sense when it is relevant to all of the data being processed -- if you want to manage flow of control which is not relevant to the entire set of data being processed you might artificially reduce the amount of data being processed, along the lines of an SQL cursor).
Note also that both functions take the same argument.


=={{header|Java}}==
=={{header|Java}}==
In Java the boolean operators <code>&&</code> and <code>||</code> are short circuit operators. The eager operator counterparts are <code>&</code> and <code>|</code>.
In Java the boolean operators <code>&&</code> and <code>||</code> are short circuit operators. The eager operator counterparts are <code>&</code> and <code>|</code>.
<lang java>public class ShortCirc {
<syntaxhighlight lang="java">public class ShortCirc {
public static void main(String[] args){
public static void main(String[] args){
System.out.println("F and F = " + (a(false) && b(false)) + "\n");
System.out.println("F and F = " + (a(false) && b(false)) + "\n");
Line 279: Line 2,119:
return b;
return b;
}
}
}</lang>
}</syntaxhighlight>
{{out}}
Output:
<pre>a
<pre>a
F and F = false
F and F = false
Line 308: Line 2,148:
a
a
T or T = true</pre>
T or T = true</pre>

=={{header|JavaScript}}==

Short-circuiting evaluation of boolean expressions has been the default since the first versions of JavaScript.

<syntaxhighlight lang="javascript">(function () {
'use strict';

function a(bool) {
console.log('a -->', bool);

return bool;
}

function b(bool) {
console.log('b -->', bool);

return bool;
}
var x = a(false) && b(true),
y = a(true) || b(false),
z = true ? a(true) : b(false);
return [x, y, z];
})();</syntaxhighlight>

The console log shows that in each case (the binding of all three values), only the left-hand part of the expression (the application of ''a(expr)'') was evaluated – ''b(expr)'' was skipped by logical short-circuiting.

{{Out}}

Console:
<pre>/* a --> false */
/* a --> true */
/* a --> true */</pre>

Return value:
<pre>[false, true, true]</pre>

=={{header|jq}}==
jq's 'and' and 'or' are short-circuit operators. The following demonstration, which follows the "awk" example above, requires a version of jq with the built-in filter 'stderr'.
<syntaxhighlight lang="jq">def a(x): " a(\(x))" | stderr | x;

def b(y): " b(\(y))" | stderr | y;

"and:", (a(true) and b(true)),
"or:", (a(true) or b(true)),
"and:", (a(false) and b(true)),
"or:", (a(false) or b(true))</syntaxhighlight>
{{out}}
<syntaxhighlight lang="sh">$ jq -r -n -f Short-circuit-evaluation.jq
and:
" a(true)"
" b(true)"
true
or:
" a(true)"
true
and:
" a(false)"
false
or:
" a(false)"
" b(true)"
true</syntaxhighlight>

=={{header|Julia}}==
Julia does have short-circuit evaluation, which works just as you expect it to:

<syntaxhighlight lang="julia">a(x) = (println("\t# Called a($x)"); return x)
b(x) = (println("\t# Called b($x)"); return x)

for i in [true,false], j in [true, false]
println("\nCalculating: x = a($i) && b($j)"); x = a(i) && b(j)
println("\tResult: x = $x")
println("\nCalculating: y = a($i) || b($j)"); y = a(i) || b(j)
println("\tResult: y = $y")
end</syntaxhighlight>
{{out}}
<pre>Calculating: x = a(true) && b(true)
# Called a(true)
# Called b(true)
Result: x = true

Calculating: y = a(true) || b(true)
# Called a(true)
Result: y = true

Calculating: x = a(true) && b(false)
# Called a(true)
# Called b(false)
Result: x = false

Calculating: y = a(true) || b(false)
# Called a(true)
Result: y = true

Calculating: x = a(false) && b(true)
# Called a(false)
Result: x = false

Calculating: y = a(false) || b(true)
# Called a(false)
# Called b(true)
Result: y = true

Calculating: x = a(false) && b(false)
# Called a(false)
Result: x = false

Calculating: y = a(false) || b(false)
# Called a(false)
# Called b(false)
Result: y = false</pre>

=={{header|Kotlin}}==
<syntaxhighlight lang="scala">// version 1.1.2

fun a(v: Boolean): Boolean {
println("'a' called")
return v
}

fun b(v: Boolean): Boolean {
println("'b' called")
return v
}

fun main(args: Array<String>){
val pairs = arrayOf(Pair(true, true), Pair(true, false), Pair(false, true), Pair(false, false))
for (pair in pairs) {
val x = a(pair.first) && b(pair.second)
println("${pair.first} && ${pair.second} = $x")
val y = a(pair.first) || b(pair.second)
println("${pair.first} || ${pair.second} = $y")
println()
}
}</syntaxhighlight>

{{out}}
<pre>
'a' called
'b' called
true && true = true
'a' called
true || true = true

'a' called
'b' called
true && false = false
'a' called
true || false = true

'a' called
false && true = false
'a' called
'b' called
false || true = true

'a' called
false && false = false
'a' called
'b' called
false || false = false
</pre>

=={{header|Lambdatalk}}==
Short-circuiting evaluation of boolean expressions has been the default since the first versions of lambdatalk.
<syntaxhighlight lang="scheme">
{def A {lambda {:bool} :bool}} -> A
{def B {lambda {:bool} :bool}} -> B

{and {A true} {B true}} -> true
{and {A true} {B false}} -> false
{and {A false} {B true}} -> false
{and {A false} {B false}} -> false

{or {A true} {B true}} -> true
{or {A true} {B false}} -> true
{or {A false} {B true}} -> true
{or {A false} {B false}} -> false
</syntaxhighlight>

Some more words about short-circuit evaluation. Lambdatalk comes with the {if "bool" then "one" else "two"} special form where "one" or "two" are not evaluated until "bool" is. This behaviour prevents useless computing and allows recursive processes. For instance, the naïve fibonacci function quickly leads to extensive computings.
<syntaxhighlight lang="scheme">

{def fib
{lambda {:n}
{if {< :n 2}
then 1
else {+ {fib {- :n 1}} {fib {- :n 2}}}}}}
-> fib

1) Using the if special form:

{if true then {+ 1 2} else {fib 29}}
-> 3 // {fib 29} is not evaluated

{if false then {+ 1 2} else {fib 29}}
-> 832040 // {fib 29} is evaluated in 5847ms

2) The if special form can't be simply replaced by a pair:

{def when {P.new {+ 1 2} {fib 29}}} // inner expressions are
{P.left {when}} -> 3 // both evaluated before
{P.right {when}} -> 832040 // and we don't want that

3) We can delay evaluation using lambdas:

{def when
{P.new {lambda {} {+ 1 2}} // will return a lambda
{lambda {} {fib 22}} }} // to be evaluated later
-> when
{{P.left {when}}} -> 3 // lambdas are evaluated
{{P.right {when}}} -> 832040 // after choice using {}

</syntaxhighlight>

=={{header|Liberty BASIC}}==
LB does not have short-circuit evaluation. Implemented with IFs.
<syntaxhighlight lang="lb">print "AND"
for i = 0 to 1
for j = 0 to 1
print "a("; i; ") AND b( "; j; ")"
res =a( i) 'call always
if res <>0 then 'short circuit if 0
res = b( j)
end if
print "=>",res
next
next

print "---------------------------------"
print "OR"
for i = 0 to 1
for j = 0 to 1
print "a("; i; ") OR b("; j; ")"
res =a( i) 'call always
if res = 0 then 'short circuit if <>0
res = b( j)
end if
print "=>", res
next
next

'----------------------------------------
function a( t)
print ,"calls func a"
a = t
end function

function b( t)
print ,"calls func b"
b = t
end function </syntaxhighlight>
{{out}}
<pre>AND
a(0) AND b( 0)
calls func a
=> 0
a(0) AND b( 1)
calls func a
=> 0
a(1) AND b( 0)
calls func a
calls func b
=> 0
a(1) AND b( 1)
calls func a
calls func b
=> 1
---------------------------------
OR
a(0) OR b(0)
calls func a
calls func b
=> 0
a(0) OR b(1)
calls func a
calls func b
=> 1
a(1) OR b(0)
calls func a
=> 1
a(1) OR b(1)
calls func a
=> 1</pre>

=={{header|LiveCode}}==
Livecode uses short-circuit evaluation.
<syntaxhighlight lang="livecode">global outcome
function a bool
put "a called with" && bool & cr after outcome
return bool
end a
function b bool
put "b called with" && bool & cr after outcome
return bool
end b

on mouseUp
local tExp
put empty into outcome
repeat for each item op in "and,or"
repeat for each item x in "true,false"
put merge("a([[x]]) [[op]] b([[x]])") into tExp
put merge(tExp && "is [[" & tExp & "]]") & cr after outcome
put merge("a([[x]]) [[op]] b([[not x]])") into tExp
put merge(tExp && "is [[" & tExp & "]]") & cr after outcome
end repeat
put cr after outcome
end repeat
put outcome
end mouseUp</syntaxhighlight>

=={{header|Logo}}==
The <code>AND</code> and <code>OR</code> predicates may take either expressions which are all evaluated beforehand, or lists which are short-circuit evaluated from left to right only until the overall value of the expression can be determined.
<syntaxhighlight lang="logo">and [notequal? :x 0] [1/:x > 3]
(or [:x < 0] [:y < 0] [sqrt :x + sqrt :y < 3])</syntaxhighlight>

=={{header|Lua}}==
<syntaxhighlight lang="lua">function a(i)
print "Function a(i) called."
return i
end

function b(i)
print "Function b(i) called."
return i
end

i = true
x = a(i) and b(i); print ""
y = a(i) or b(i); print ""

i = false
x = a(i) and b(i); print ""
y = a(i) or b(i)</syntaxhighlight>

=={{header|M2000 Interpreter}}==
<syntaxhighlight lang="m2000 interpreter">
Module Short_circuit_evaluation {
function a(a as boolean) {
=a
doc$<=format$(" Called function a({0}) -> {0}", a)+{
}
}
function b(b as boolean) {
=b
doc$<=format$(" Called function b({0}) -> {0}", b)+{
}
}
boolean T=true, F, iv, jv
variant L=(F, T), i, j
i=each(L)
global doc$ : document doc$
while i
j=each(L)
while j
(iv, jv)=(array(i), array(j))
doc$<=format$("Calculating x = a({0}) and b({1}) -> {2}", iv, jv, iv and jv)+{
}
x=if(a(iv)->b(jv), F)
doc$<=format$("x={0}", x)+{
}+ format$("Calculating y = a({0}) or b({1}) -> {2}", iv, jv, iv or jv)+{
}
y=if(a(iv)->T, b(jv))
doc$<=format$("y={0}", y)+{
}
end while
end while
clipboard doc$
report doc$
}
Short_circuit_evaluation
</syntaxhighlight>
{{out}}
<pre>
Calculating x = a(False) and b(False) -> False
Called function a(False) -> False
x=False
Calculating y = a(False) or b(False) -> False
Called function a(False) -> False
Called function b(False) -> False
y=False

Calculating x = a(False) and b(True) -> False
Called function a(False) -> False
x=False
Calculating y = a(False) or b(True) -> True
Called function a(False) -> False
Called function b(True) -> True
y=True

Calculating x = a(True) and b(False) -> False
Called function a(True) -> True
Called function b(False) -> False
x=False
Calculating y = a(True) or b(False) -> True
Called function a(True) -> True
y=True

Calculating x = a(True) and b(True) -> True
Called function a(True) -> True
Called function b(True) -> True
x=True
Calculating y = a(True) or b(True) -> True
Called function a(True) -> True
y=True

</pre>

=={{header|Maple}}==
Built-in short circuit evaluation
<syntaxhighlight lang="maple">a := proc(bool)
printf("a is called->%s\n", bool):
return bool:
end proc:
b := proc(bool)
printf("b is called->%s\n", bool):
return bool:
end proc:
for i in [true, false] do
for j in [true, false] do
printf("calculating x := a(i) and b(j)\n"):
x := a(i) and b(j):
printf("calculating x := a(i) or b(j)\n"):
y := a(i) or b(j):
od:
od:</syntaxhighlight>
{{Out|Output}}
<pre>calculating x := a(i) and b(j)
a is called->true
b is called->true
calculating x := a(i) or b(j)
a is called->true
calculating x := a(i) and b(j)
a is called->true
b is called->false
calculating x := a(i) or b(j)
a is called->true
calculating x := a(i) and b(j)
a is called->false
calculating x := a(i) or b(j)
a is called->false
b is called->true
calculating x := a(i) and b(j)
a is called->false
calculating x := a(i) or b(j)
a is called->false
b is called->false</pre>

=={{header|Mathematica}}/{{header|Wolfram Language}}==
Mathematica has built-in short-circuit evaluation of logical expressions.
<syntaxhighlight lang="mathematica">a[in_] := (Print["a"]; in)
b[in_] := (Print["b"]; in)
a[False] && b[True]
a[True] || b[False]</syntaxhighlight>
Evaluation of the preceding code gives:
<pre>a
False
a
True</pre>
Whereas evaluating this:
<syntaxhighlight lang="mathematica">a[True] && b[False]</syntaxhighlight>
Gives:
<pre>a
b
False</pre>

=={{header|MATLAB}} / {{header|Octave}}==
Short-circuit evalation is done in logical AND (&&) and logical OR (||) operators:
<syntaxhighlight lang="matlab"> function x=a(x)
printf('a: %i\n',x);
end;
function x=b(x)
printf('b: %i\n',x);
end;

a(1) && b(1)
a(0) && b(1)
a(1) || b(1)
a(0) || b(1)</syntaxhighlight>
{{out}}
<syntaxhighlight lang="matlab"> > a(1) && b(1);
a: 1
b: 1
> a(0) && b(1);
a: 0
> a(1) || b(1);
a: 1
> a(0) || b(1);
a: 0
b: 1</syntaxhighlight>

=={{header|Modula-2}}==
<syntaxhighlight lang="modula2">MODULE ShortCircuit;
FROM FormatString IMPORT FormatString;
FROM Terminal IMPORT WriteString,WriteLn,ReadChar;

PROCEDURE a(v : BOOLEAN) : BOOLEAN;
VAR buf : ARRAY[0..63] OF CHAR;
BEGIN
FormatString(" # Called function a(%b)\n", buf, v);
WriteString(buf);
RETURN v
END a;

PROCEDURE b(v : BOOLEAN) : BOOLEAN;
VAR buf : ARRAY[0..63] OF CHAR;
BEGIN
FormatString(" # Called function b(%b)\n", buf, v);
WriteString(buf);
RETURN v
END b;

PROCEDURE Print(x,y : BOOLEAN);
VAR buf : ARRAY[0..63] OF CHAR;
VAR temp : BOOLEAN;
BEGIN
FormatString("a(%b) AND b(%b)\n", buf, x, y);
WriteString(buf);
temp := a(x) AND b(y);

FormatString("a(%b) OR b(%b)\n", buf, x, y);
WriteString(buf);
temp := a(x) OR b(y);

WriteLn;
END Print;

BEGIN
Print(FALSE,FALSE);
Print(FALSE,TRUE);
Print(TRUE,TRUE);
Print(TRUE,FALSE);
ReadChar
END ShortCircuit.</syntaxhighlight>


=={{header|MUMPS}}==
=={{header|MUMPS}}==
<p>MUMPS evaluates every expression it encounters, so we have to use conditional statements to do a short circuiting of the expensive second task.</p>
MUMPS evaluates every expression it encounters, so we have to use conditional statements to do a short circuiting of the expensive second task.
<lang MUMPS>SSEVAL1(IN)
<syntaxhighlight lang="mumps">SSEVAL1(IN)
WRITE !,?10,$STACK($STACK,"PLACE")
WRITE !,?10,$STACK($STACK,"PLACE")
QUIT IN
QUIT IN
Line 332: Line 2,713:
WRITE !,$SELECT(Z:"TRUE",1:"FALSE")
WRITE !,$SELECT(Z:"TRUE",1:"FALSE")
KILL Z
KILL Z
QUIT</lang>
QUIT</syntaxhighlight>
{{out}}
Output:<pre>USER>D SSEVAL3^ROSETTA
<pre>USER>D SSEVAL3^ROSETTA
1 AND 1
1 AND 1
SSEVAL1+1^ROSETTA +3
SSEVAL1+1^ROSETTA +3
Line 350: Line 2,732:
SSEVAL1+1^ROSETTA +3
SSEVAL1+1^ROSETTA +3
SSEVAL2+1^ROSETTA +3
SSEVAL2+1^ROSETTA +3
TRUE
TRUE</pre>

=={{header|Nanoquery}}==
Nanoquery does not short-circuit by default, so short-circuit logic functions have been implemented by nested ifs.
<syntaxhighlight lang="nanoquery">def short_and(bool1, bool2)
global a
global b
if a(bool1)
if b(bool2)
return true
else
return false
end
else
return false
end
end

def short_or(bool1, bool2)
if a(bool1)
return true
else
if b(bool2)
return true
else
return false
end
end
end

def a(bool)
println "a called."
return bool
end

def b(bool)
println "b called."
return bool
end

println "F and F = " + short_and(false, false) + "\n"
println "F or F = " + short_or(false, false) + "\n"

println "F and T = " + short_and(false, true) + "\n"
println "F or T = " + short_or(false, true) + "\n"

println "T and F = " + short_and(true, false) + "\n"
println "T or F = " + short_or(true, false) + "\n"

println "T and T = " + short_and(true, true) + "\n"
println "T or T = " + short_or(true, true) + "\n"</syntaxhighlight>
{{out}}
<pre>a called.
F and F = false

a called.
b called.
F or F = false

a called.
F and T = false

a called.
b called.
F or T = true

a called.
b called.
T and F = false

a called.
T or F = true

a called.
b called.
T and T = true

a called.
T or T = true
</pre>
</pre>


=={{header|OCaml}}==
=={{header|Nemerle}}==
<syntaxhighlight lang="nemerle">using System.Console;


class ShortCircuit
<lang ocaml>
{
let a r = print_endline " > function a called"; r
public static a(x : bool) : bool
{
WriteLine("a");
x
}

public static b(x : bool) : bool
{
WriteLine("b");
x
}
public static Main() : void
{
def t = true;
def f = false;

WriteLine("True && True : {0}", a(t) && b(t));
WriteLine("True && False: {0}", a(t) && b(f));
WriteLine("False && True : {0}", a(f) && b(t));
WriteLine("False && False: {0}", a(f) && b(f));
WriteLine("True || True : {0}", a(t) || b(t));
WriteLine("True || False: {0}", a(t) || b(f));
WriteLine("False || True : {0}", a(f) || b(t));
WriteLine("False || False: {0}", a(f) || b(f));
}
}</syntaxhighlight>
{{out}}
<syntaxhighlight lang="text">a
b
True && True : True
a
b
True && False: False
a
False && True : False
a
False && False: False
a
True || True : True
a
True || False: True
a
b
False || True : True
a
b
False || False: False</syntaxhighlight>

=={{header|NetRexx}}==
{{trans|ooRexx}}
Like [[OoRexx]], [[NetRexx]] allows a list of expressions in the condition part of <tt>If</tt> and <tt>When</tt>. Evaluation ends with the first of these expressions resulting in <tt>boolean true</tt>.
<syntaxhighlight lang="netrexx">/* NetRexx */
options replace format comments java crossref symbols nobinary

Parse Version v
Say 'Version='v

If a() | b() Then Say 'a and b are true'
If \a() | b() Then Say 'Surprise'
Else Say 'ok'

If a(), b() Then Say 'a is true'
If \a(), b() Then Say 'Surprise'
Else Say 'ok: \\a() is false'

Select
When \a(), b() Then Say 'Surprise'
Otherwise Say 'ok: \\a() is false (Select)'
End
Return

method a private static binary returns boolean
state = Boolean.TRUE.booleanValue()
Say '--a returns' state
Return state

method b private static binary returns boolean
state = Boolean.TRUE.booleanValue()
Say '--b returns' state
Return state
</syntaxhighlight>
{{out}}
<pre>
Version=NetRexx 3.03 11 Jun 2014
--a returns 1
--b returns 1
a and b are true
--a returns 1
--b returns 1
Surprise
--a returns 1
a is true
--a returns 1
--b returns 1
Surprise
--a returns 1
--b returns 1
Surprise

</pre>

=={{header|Nim}}==
Nim produces code which uses short-circuit evaluation.
<syntaxhighlight lang="nim">proc a(x): bool =
echo "a called"
result = x

proc b(x): bool =
echo "b called"
result = x

let x = a(false) and b(true) # echoes "a called"
let y = a(true) or b(true) # echoes "a called"</syntaxhighlight>

=={{header|Objeck}}==
In Objeck the Boolean operators <code>&</code> and <code>|</code> short circuit.
<syntaxhighlight lang="objeck">class ShortCircuit {
function : a(a : Bool) ~ Bool {
"a"->PrintLine();
return a;
}

function : b(b : Bool) ~ Bool {
"b"->PrintLine();
return b;
}

function : Main(args : String[]) ~ Nil {
result := a(false) & b(false);
"F and F = {$result}"->PrintLine();
result := a(false) | b(false);
"F or F = {$result}"->PrintLine();

result := a(false) & b(true);
"F and T = {$result}"->PrintLine();
result := a(false) | b(true);
"F or T = {$result}"->PrintLine();

result := a(true) & b(false);
"T and F = {$result}"->PrintLine();
result := a(true) | b(false);
"T or F = {$result}"->PrintLine();

result := a(true) & b(true);
"T and T = {$result}"->PrintLine();
result := a(true) | b(true);
"T or T = {$result}"->PrintLine();
}
}</syntaxhighlight>

=={{header|OCaml}}==
<syntaxhighlight lang="ocaml">let a r = print_endline " > function a called"; r
let b r = print_endline " > function b called"; r
let b r = print_endline " > function b called"; r


Line 379: Line 2,993:
print_endline "==== Testing or ====";
print_endline "==== Testing or ====";
test_this test_or;
test_this test_or;
;;</lang>
;;</syntaxhighlight>
{{out}}

output:

==== Testing and ====
==== Testing and ====
# testing (true && true)
# testing (true && true)
Line 406: Line 3,018:
> function b called
> function b called


=={{header|Logo}}==
=={{header|Ol}}==
<syntaxhighlight lang="scheme">
(define (a x)
(print " (a) => " x)
x)


(define (b x)
The AND and OR predicates may take either expressions which are all evaluated beforehand, or lists which are short-circuit evaluated from left to right only until the overall value of the expression can be determined.
(print " (b) => " x)
<lang logo>
x)
and [notequal? :x 0] [1/:x > 3]

(or [:x < 0] [:y < 0] [sqrt :x + sqrt :y < 3])
; and
</lang>
(print " -- and -- ")
(for-each (lambda (x y)
(print "let's evaluate '(a as " x ") and (b as " y ")':")
(let ((out (and (a x) (b y))))
(print " result is " out)))
'(#t #t #f #f)
'(#t #f #t #f))

; or
(print " -- or -- ")
(for-each (lambda (x y)
(print "let's evaluate '(a as " x ") or (b as " y ")':")
(let ((out (or (a x) (b y))))
(print " result is " out)))
'(#t #t #f #f)
'(#t #f #t #f))
</syntaxhighlight>
{{Out}}
<pre>
-- and --
let's evaluate '(a as #true) and (b as #true)':
(a) => #true
(b) => #true
result is #true
let's evaluate '(a as #true) and (b as #false)':
(a) => #true
(b) => #false
result is #false
let's evaluate '(a as #false) and (b as #true)':
(a) => #false
result is #false
let's evaluate '(a as #false) and (b as #false)':
(a) => #false
result is #false
-- or --
let's evaluate '(a as #true) or (b as #true)':
(a) => #true
result is #true
let's evaluate '(a as #true) or (b as #false)':
(a) => #true
result is #true
let's evaluate '(a as #false) or (b as #true)':
(a) => #false
(b) => #true
result is #true
let's evaluate '(a as #false) or (b as #false)':
(a) => #false
(b) => #false
result is #false
</pre>

=={{header|ooRexx}}==
ooRexx allows a list of expressions in the condition part of If and When.
Evaluation ends with the first of these expressions resulting in .false (or 0).
<syntaxhighlight lang="oorexx">Parse Version v
Say 'Version='v
If a() | b() Then Say 'a and b are true'
If \a() | b() Then Say 'Surprise'
Else Say 'ok'
If a(), b() Then Say 'a is true'
If \a(), b() Then Say 'Surprise'
Else Say 'ok: \a() is false'
Select
When \a(), b() Then Say 'Surprise'
Otherwise Say 'ok: \a() is false (Select)'
End
Exit
a: Say 'a returns .true'; Return .true
b: Say 'b returns 1'; Return 1
</syntaxhighlight>
{{out}}
<pre>Version=REXX-ooRexx_4.2.0(MT)_32-bit 6.04 22 Feb 2014
a returns .true
b returns 1
a and b are true
a returns .true
b returns 1
Surprise
a returns .true
b returns 1
a is true
a returns .true
ok: \a() is false
a returns .true
ok: \a() is false (Select)
</pre>


=={{header|Oz}}==
=={{header|Oz}}==
Oz' <code>andthen</code> and <code>orelse</code> operators are short-circuiting, as indicated by their name. The library functions <code>Bool.and</code> and <code>Bool.or</code> are not short-circuiting, on the other hand.
Oz' <code>andthen</code> and <code>orelse</code> operators are short-circuiting, as indicated by their name. The library functions <code>Bool.and</code> and <code>Bool.or</code> are not short-circuiting, on the other hand.
<syntaxhighlight lang="oz">declare

<lang oz>declare
fun {A Answer}
fun {A Answer}
AnswerS = {Value.toVirtualString Answer 1 1}
AnswerS = {Value.toVirtualString Answer 1 1}
Line 441: Line 3,142:
Y = {A I} orelse {B J}
Y = {A I} orelse {B J}
end
end
end</lang>
end</syntaxhighlight>
{{out}}

<syntaxhighlight lang="oz">Calculating: X = {A I} andthen {B J}
Output:
<lang oz>Calculating: X = {A I} andthen {B J}
% Called function {A false} -> false
% Called function {A false} -> false
Calculating: Y = {A I} orelse {B J}
Calculating: Y = {A I} orelse {B J}
Line 466: Line 3,166:
% Called function {B true} -> true
% Called function {B true} -> true
Calculating: Y = {A I} orelse {B J}
Calculating: Y = {A I} orelse {B J}
% Called function {A true} -> true</lang>
% Called function {A true} -> true</syntaxhighlight>

=={{header|PARI/GP}}==
Note that <code>|</code> and <code>&</code> are deprecated versions of the GP short-circuit operators.
<syntaxhighlight lang="parigp">a(n)={
print(a"("n")");
a
};
b(n)={
print("b("n")");
n
};
or(A,B)={
a(A) || b(B)
};
and(A,B)={
a(A) && b(B)
};</syntaxhighlight>


=={{header|Pascal}}==
=={{header|Pascal}}==
===Standard Pascal===
===Standard Pascal===
Standard Pascal doesn't have native short-circuit evaluation.
Standard Pascal doesn't have native short-circuit evaluation.
<syntaxhighlight lang="pascal">program shortcircuit(output);
<lang pascal>
program shortcircuit(output);


function a(value: boolean): boolean;
function a(value: boolean): boolean;
Line 488: Line 3,204:
procedure scandor(value1, value2: boolean);
procedure scandor(value1, value2: boolean);
var
var
result: integer;
result: boolean;
begin
begin
{and}
{and}
Line 504: Line 3,220:
else
else
result := b(value2)
result := b(value2)
writeln(value1, ' or ', value2, ' = ', result)
writeln(value1, ' or ', value2, ' = ', result);
end;
end;


Line 512: Line 3,228:
scandor(true, false);
scandor(true, false);
scandor(true, true);
scandor(true, true);
end.</syntaxhighlight>
end.
</lang>


===Turbo Pascal===
===Turbo Pascal===
Turbo Pascal allows short circuit evaluation with a compiler switch:
Turbo Pascal allows short circuit evaluation with a compiler switch:
<syntaxhighlight lang="pascal">program shortcircuit;
<lang pascal>
program shortcircuit;


function a(value: boolean): boolean;
function a(value: boolean): boolean;
begin
begin
writeln('a(', value, ')');
writeln('a(', value, ')');
a := value
a := value;
end;
end;


Line 529: Line 3,243:
begin
begin
writeln('b(', value, ')');
writeln('b(', value, ')');
b := value
b := value;
end;
end;


Line 535: Line 3,249:
procedure scandor(value1, value2: boolean);
procedure scandor(value1, value2: boolean);
var
var
result: integer;
result: boolean;
begin
begin
result := a(value1) and b(value)
result := a(value1) and b(value);
writeln(value1, ' and ', value2, ' = ', result);
writeln(value1, ' and ', value2, ' = ', result);


result := a(value1) or b(value2);
result := a(value1) or b(value2);
writeln(value1, ' or ', value2, ' = ', result)
writeln(value1, ' or ', value2, ' = ', result);
end;
end;


Line 549: Line 3,263:
scandor(true, false);
scandor(true, false);
scandor(true, true);
scandor(true, true);
end.</syntaxhighlight>
end.
</lang>

===Extended Pascal===
===Extended Pascal===
The extended Pascal standard introduces the operators <code>and_then</code> and <code>or_else</code> for short-circuit evaluation.
The extended Pascal standard introduces the operators <code>and_then</code> and <code>or_else</code> for short-circuit evaluation.
<syntaxhighlight lang="pascal">program shortcircuit(output);
<lang pascal>
program shortcircuit(output);


function a(value: boolean): boolean;
function a(value: boolean): boolean;
Line 585: Line 3,296:
scandor(true, false);
scandor(true, false);
scandor(true, true);
scandor(true, true);
end.</syntaxhighlight>
end.
</lang>

Note: GNU Pascal allows <code>and then</code> and <code>or else</code> as alternatives to <code>and_then</code> and <code>or_else</code>.
Note: GNU Pascal allows <code>and then</code> and <code>or else</code> as alternatives to <code>and_then</code> and <code>or_else</code>.


=={{header|Perl}}==
=={{header|Perl}}==

Perl uses short-circuit boolean evaluation.
Perl uses short-circuit boolean evaluation.
<syntaxhighlight lang="perl">sub a { print 'A'; return $_[0] }

<lang Perl>sub a { print 'A'; return $_[0] }
sub b { print 'B'; return $_[0] }
sub b { print 'B'; return $_[0] }


Line 607: Line 3,314:


# Test and display
# Test and display
test();</lang>
test();</syntaxhighlight>
{{out}}

Output:
<pre>a(1) && b(1): AB
<pre>a(1) && b(1): AB
a(1) && b(0): AB
a(1) && b(0): AB
Line 618: Line 3,324:
a(0) || b(1): AB
a(0) || b(1): AB
a(0) || b(0): AB</pre>
a(0) || b(0): AB</pre>

=={{header|Phix}}==
In Phix all expressions are short circuited
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"a "</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">i</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"b "</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">i</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">z</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">z</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"a(%d) and b(%d) "</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">j</span><span style="color: #0000FF;">})</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" =&gt; %d\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">a</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">and</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">(</span><span style="color: #000000;">j</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">else</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"a(%d) or b(%d) "</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">j</span><span style="color: #0000FF;">})</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" =&gt; %d\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">a</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">or</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">(</span><span style="color: #000000;">j</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{Out}}
<pre>
a(0) or b(0) a b => 0
a(0) or b(1) a b => 1
a(1) or b(0) a => 1
a(1) or b(1) a => 1
a(0) and b(0) a => 0
a(0) and b(1) a => 0
a(1) and b(0) a b => 0
a(1) and b(1) a b => 1
</pre>


=={{header|PicoLisp}}==
=={{header|PicoLisp}}==
<lang PicoLisp>(de a (F)
<syntaxhighlight lang="picolisp">(de a (F)
(msg 'a)
(msg 'a)
F )
F )
Line 633: Line 3,379:
(println I Op J '-> (Op (a I) (b J))) ) )
(println I Op J '-> (Op (a I) (b J))) ) )
'(NIL NIL T T)
'(NIL NIL T T)
'(NIL T NIL T) )</lang>
'(NIL T NIL T) )</syntaxhighlight>
{{out}}
Output:
<pre>a
<pre>a
NIL and NIL -> NIL
NIL and NIL -> NIL
Line 655: Line 3,401:
a
a
T or T -> T</pre>
T or T -> T</pre>

=={{header|Pike}}==
<syntaxhighlight lang="pike">int(0..1) a(int(0..1) i)
{
write(" a\n");
return i;
}

int(0..1) b(int(0..1) i)
{
write(" b\n");
return i;
}

foreach(({ ({ false, false }), ({ false, true }), ({ true, true }), ({ true, false }) });; array(int) args)
{
write(" %d && %d\n", @args);
a(args[0]) && b(args[1]);
write(" %d || %d\n", @args);
a(args[0]) || b(args[1]);
}</syntaxhighlight>
{{out}}
<pre>
0 && 0
a
0 || 0
a
b
0 && 1
a
0 || 1
a
b
1 && 1
a
b
1 || 1
a
1 && 0
a
b
1 || 0
a
</pre>

=={{header|PL/I}}==
<syntaxhighlight lang="pli">short_circuit_evaluation:
procedure options (main);
declare (true initial ('1'b), false initial ('0'b) ) bit (1);
declare (i, j, x, y) bit (1);

a: procedure (bv) returns (bit(1));
declare bv bit(1);
put ('Procedure ' || procedurename() || ' called.');
return (bv);
end a;
b: procedure (bv) returns (bit(1));
declare bv bit(1);
put ('Procedure ' || procedurename() || ' called.');
return (bv);
end b;

do i = true, false;
do j = true, false;
put skip(2) list ('Evaluating x with <a> with ' || i || ' and <b> with ' || j);
put skip;
if a(i) then
x = b(j);
else
x = false;
put skip data (x);
put skip(2) list ('Evaluating y with <a> with ' || i || ' and <b> with ' || j);
put skip;
if a(i) then
y = true;
else
y = b(j);
put skip data (y);
end;
end;
end short_circuit_evaluation;</syntaxhighlight>
{{out|Results}}
<pre>
Evaluating x with <a> with 1 and <b> with 1
Procedure A called. Procedure B called.
X='1'B;

Evaluating y with <a> with 1 and <b> with 1
Procedure A called.
Y='1'B;

Evaluating x with <a> with 1 and <b> with 0
Procedure A called. Procedure B called.
X='0'B;

Evaluating y with <a> with 1 and <b> with 0
Procedure A called.
Y='1'B;

Evaluating x with <a> with 0 and <b> with 1
Procedure A called.
X='0'B;

Evaluating y with <a> with 0 and <b> with 1
Procedure A called. Procedure B called.
Y='1'B;

Evaluating x with <a> with 0 and <b> with 0
Procedure A called.
X='0'B;

Evaluating y with <a> with 0 and <b> with 0
Procedure A called. Procedure B called.
Y='0'B;
</pre>

=={{header|PowerShell}}==
PowerShell handles this natively.
<syntaxhighlight lang="powershell"># Simulated fast function
function a ( [boolean]$J ) { return $J }
# Simulated slow function
function b ( [boolean]$J ) { Sleep -Seconds 2; return $J }
# These all short-circuit and do not evaluate the right hand function
( a $True ) -or ( b $False )
( a $True ) -or ( b $True )
( a $False ) -and ( b $False )
( a $False ) -and ( b $True )
# Measure of execution time
Measure-Command {
( a $True ) -or ( b $False )
( a $True ) -or ( b $True )
( a $False ) -and ( b $False )
( a $False ) -and ( b $True )
} | Select TotalMilliseconds
# These all appropriately do evaluate the right hand function
( a $False ) -or ( b $False )
( a $False ) -or ( b $True )
( a $True ) -and ( b $False )
( a $True ) -and ( b $True )
# Measure of execution time
Measure-Command {
( a $False ) -or ( b $False )
( a $False ) -or ( b $True )
( a $True ) -and ( b $False )
( a $True ) -and ( b $True )
} | Select TotalMilliseconds</syntaxhighlight>
{{out}}
<pre>True
True
False
False

TotalMilliseconds
-----------------
15.653
False
True
False
True
8012.9405</pre>

=={{header|Prolog}}==
Prolog has not functions but predicats succeed of fail.
Tested with SWI-Prolog. Should work with other dialects.
<syntaxhighlight lang="prolog">short_circuit :-
( a_or_b(true, true) -> writeln('==> true'); writeln('==> false')) , nl,
( a_or_b(true, false)-> writeln('==> true'); writeln('==> false')) , nl,
( a_or_b(false, true)-> writeln('==> true'); writeln('==> false')) , nl,
( a_or_b(false, false)-> writeln('==> true'); writeln('==> false')) , nl,
( a_and_b(true, true)-> writeln('==> true'); writeln('==> false')) , nl,
( a_and_b(true, false)-> writeln('==> true'); writeln('==> false')) , nl,
( a_and_b(false, true)-> writeln('==> true'); writeln('==> false')) , nl,
( a_and_b(false, false)-> writeln('==> true'); writeln('==> false')) .


a_and_b(X, Y) :-
format('a(~w) and b(~w)~n', [X, Y]),
( a(X), b(Y)).

a_or_b(X, Y) :-
format('a(~w) or b(~w)~n', [X, Y]),
( a(X); b(Y)).

a(X) :-
format('a(~w)~n', [X]),
X.

b(X) :-
format('b(~w)~n', [X]),
X.</syntaxhighlight>
{{out}}
<syntaxhighlight lang="prolog">?- short_circuit.
a(true) or b(true)
a(true)
==> true

a(true) or b(false)
a(true)
==> true

a(false) or b(true)
a(false)
b(true)
==> true

a(false) or b(false)
a(false)
b(false)
==> false

a(true) and b(true)
a(true)
b(true)
==> true

a(true) and b(false)
a(true)
b(false)
==> false

a(false) and b(true)
a(false)
==> false

a(false) and b(false)
a(false)
==> false

true.</syntaxhighlight>


=={{header|PureBasic}}==
=={{header|PureBasic}}==
Logical '''And''' & '''Or''' operators will not evaluate their right-hand expression if the outcome can be determined from the value of the left-hand expression.
Logical '''And''' &amp; '''Or''' operators will not evaluate their right-hand expression if the outcome can be determined from the value of the left-hand expression.
<lang PureBasic>Procedure a(arg)
<syntaxhighlight lang="purebasic">Procedure a(arg)
PrintN(" # Called function a("+Str(arg)+")")
PrintN(" # Called function a("+Str(arg)+")")
ProcedureReturn arg
ProcedureReturn arg
Line 677: Line 3,658:
Next
Next
Next
Next
Input()</lang>
Input()</syntaxhighlight>
{{out}}
<pre>Calculating: x = a(0) And b(0)
<pre>Calculating: x = a(0) And b(0)
# Called function a(0)
# Called function a(0)
Line 704: Line 3,686:
=={{header|Python}}==
=={{header|Python}}==
Pythons '''and''' and '''or''' binary, infix, boolean operators will not evaluate their right-hand expression if the outcome can be determined from the value of the left-hand expression.
Pythons '''and''' and '''or''' binary, infix, boolean operators will not evaluate their right-hand expression if the outcome can be determined from the value of the left-hand expression.
<lang python>>>> def a(answer):
<syntaxhighlight lang="python">>>> def a(answer):
print(" # Called function a(%r) -> %r" % (answer, answer))
print(" # Called function a(%r) -> %r" % (answer, answer))
return answer
return answer
Line 743: Line 3,725:
# Called function b(True) -> True
# Called function b(True) -> True
Calculating: y = a(i) or b(j)
Calculating: y = a(i) or b(j)
# Called function a(True) -> True</lang>
# Called function a(True) -> True</syntaxhighlight>

Pythons if ''expression'' can also be used to the same ends (but probably should not):
Pythons if ''expression'' can also be used to the same ends (but probably should not):
<lang python>>>> for i in (False, True):
<syntaxhighlight lang="python">>>> for i in (False, True):
for j in (False, True):
for j in (False, True):
print ("\nCalculating: x = a(i) and b(j) using x = b(j) if a(i) else False")
print ("\nCalculating: x = a(i) and b(j) using x = b(j) if a(i) else False")
Line 777: Line 3,758:
# Called function b(True) -> True
# Called function b(True) -> True
Calculating: y = a(i) or b(j) using y = b(j) if not a(i) else True
Calculating: y = a(i) or b(j) using y = b(j) if not a(i) else True
# Called function a(True) -> True</lang>
# Called function a(True) -> True</syntaxhighlight>

=={{header|Quackery}}==

Quackery does not include short-circuit evaluation, but it can be added by use of meta-control flow words (words wrapped in reverse brackets such as <code>]done[</code>.) For details see: [https://github.com/GordonCharlton/Quackery/blob/main/The%20Book%20of%20Quackery.pdf The Book of Quackery]

The short-circuit evaluation words <code>SC-and</code> and <code>SC-or</code> defined here are used thus: <code>[ a 1 SC-and b ]</code> and <code>[ a 1 SC-or b ]</code>. These presumes that the arguments to <code>a</code> and <code>b</code> are on the stack in the order <code>j i</code>.

The <code>1</code> preceding the word is required to indicate the number of arguments that <code>b</code> would consume from the stack if it were evaluated.

Extending the task to three functions, the third, <code>c</code> also consuming one argument <code>k</code> and returning a boolean, present on the stack underneath <code>j</code> and <code>i</code> would lead to the code <code>[ a 2 SC-and b 1 SC-and c ]</code> and <code>[ a 2 SC-or b 1 SC-or c ]</code>, where the <code>2</code> is the sum of the number of arguments consumed by <code>b</code> and <code>c</code>, and the <code>1</code> is the number of arguments consumed by <code>c</code>.

<code>SC-and</code> and <code>SC-or</code> can both be used in a single short-circuit evaluation nest with three or more functions. Evaluation is strictly left to right.

Quackery does not have variables, so no assignment is shown here. Words (functions) leave their results on the stack. If desired results can be moved to ancillary stacks, which include standing-in for variables amongst their functionality.

<syntaxhighlight lang="Quackery">
[ say "evaluating "
]this[ echo cr ] is ident ( --> )

[ iff say "true"
else say "false" ] is echobool ( b --> )

[ swap iff drop done
times drop
false ]done[ ] is SC-and ( b n --> )

[ swap not iff drop done
times drop
true ]done[ ] is SC-or ( b n --> )

[ ident
2 times not ] is a ( b --> b )

[ ident
4 times not ] is b ( b --> b )

[ say "i = "
dup echobool
say " AND j = "
dup echobool
cr
[ a 1 SC-and b ]
say "result is "
echobool cr cr ] is AND-demo ( --> )

[ say "i = "
dup echobool
say " OR j = "
dup echobool
cr
[ a 1 SC-or b ]
say "result is "
echobool
cr cr ] is OR-demo ( --> )

true true AND-demo
true false AND-demo
false true AND-demo
false false AND-demo
cr
true true OR-demo
true false OR-demo
false true OR-demo
false false OR-demo</syntaxhighlight>

{{out}}

<pre>i = true AND j = true
evaluating a
evaluating b
result is true

i = false AND j = false
evaluating a
result is false

i = true AND j = true
evaluating a
evaluating b
result is false

i = false AND j = false
evaluating a
result is false


i = true OR j = true
evaluating a
result is true

i = false OR j = false
evaluating a
evaluating b
result is true

i = true OR j = true
evaluating a
result is true

i = false OR j = false
evaluating a
evaluating b
result is false</pre>


=={{header|R}}==
The builtins <tt><nowiki>&&</nowiki></tt> and <tt>||</tt> will short circuit:
{{trans|Perl}}
<syntaxhighlight lang="r">a <- function(x) {cat("a called\n"); x}
b <- function(x) {cat("b called\n"); x}

tests <- expand.grid(op=list(quote(`||`), quote(`&&`)), x=c(1,0), y=c(1,0))

invisible(apply(tests, 1, function(row) {
call <- substitute(op(a(x),b(y)), row)
cat(deparse(call), "->", eval(call), "\n\n")
}))</syntaxhighlight>
{{out}}
<syntaxhighlight lang="r">a called
a(1) || b(1) -> TRUE

a called
b called
a(1) && b(1) -> TRUE

a called
b called
a(0) || b(1) -> TRUE

a called
a(0) && b(1) -> FALSE

a called
a(1) || b(0) -> TRUE

a called
b called
a(1) && b(0) -> FALSE

a called
b called
a(0) || b(0) -> FALSE

a called
a(0) && b(0) -> FALSE </syntaxhighlight>
Because R waits until function arguments are needed before evaluating them, user-defined functions can also short circuit.
<syntaxhighlight lang="r">switchop <- function(s, x, y) {
if(s < 0) x || y
else if (s > 0) x && y
else xor(x, y)
}</syntaxhighlight>
{{out}}
<syntaxhighlight lang="r">> switchop(-1, a(1), b(1))
a called
[1] TRUE
> switchop(1, a(1), b(1))
a called
b called
[1] TRUE
> switchop(1, a(0), b(1))
a called
[1] FALSE
> switchop(0, a(0), b(1))
a called
b called
[1] TRUE</syntaxhighlight>

=={{header|Racket}}==
<syntaxhighlight lang="racket">#lang racket
(define (a x)
(display (~a "a:" x " "))
x)

(define (b x)
(display (~a "b:" x " "))
x)

(for* ([x '(#t #f)]
[y '(#t #f)])
(displayln `(and (a ,x) (b ,y)))
(and (a x) (b y))
(newline)
(displayln `(or (a ,x) (b ,y)))
(or (a x) (b y))
(newline))</syntaxhighlight>
{{out}}
<pre>
(and (a #t) (b #t))
a:#t b:#t
(or (a #t) (b #t))
a:#t
(and (a #t) (b #f))
a:#t b:#f
(or (a #t) (b #f))
a:#t
(and (a #f) (b #t))
a:#f
(or (a #f) (b #t))
a:#f b:#t
(and (a #f) (b #f))
a:#f
(or (a #f) (b #f))
a:#f b:#f
</pre>

=={{header|Raku}}==
(formerly Perl 6)
{{Works with|rakudo|2018.03}}
<syntaxhighlight lang="raku" line>use MONKEY-SEE-NO-EVAL;

sub a ($p) { print 'a'; $p }
sub b ($p) { print 'b'; $p }

for 1, 0 X 1, 0 -> ($p, $q) {
for '&&', '||' -> $op {
my $s = "a($p) $op b($q)";
print "$s: ";
EVAL $s;
print "\n";
}
}</syntaxhighlight>
{{out}}
<pre>a(1) && b(1): ab
a(1) || b(1): a
a(1) && b(0): ab
a(1) || b(0): a
a(0) && b(1): a
a(0) || b(1): ab
a(0) && b(0): a
a(0) || b(0): ab</pre>

=={{header|REXX}}==
The REXX language doesn't have native short circuits &nbsp; (it's specifically mentioned in the
language specifications that
<br>short-circuiting is '''not''' supported).
<syntaxhighlight lang="rexx">/*REXX programs demonstrates short─circuit evaluation testing (in an IF statement).*/
parse arg LO HI . /*obtain optional arguments from the CL*/
if LO=='' | LO=="," then LO= -2 /*Not specified? Then use the default.*/
if HI=='' | HI=="," then HI= 2 /* " " " " " " */

do j=LO to HI /*process from the low to the high.*/
x=a(j) & b(j) /*compute function A and function B */
y=a(j) | b(j) /* " " " or " " */
if \y then y=b(j) /* " " B (for negation).*/
say copies('═', 30) ' x=' || x ' y='y ' j='j
say
end /*j*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
a: say ' A entered with:' arg(1); return abs( arg(1) // 2) /*1=odd, 0=even */
b: say ' B entered with:' arg(1); return arg(1) < 0 /*1=neg, 0=if not*/</syntaxhighlight>
{{out|output|text=&nbsp; when using the default inputs:}}
<pre>
B entered with: -2
A entered with: -2
B entered with: -2
A entered with: -2
══════════════════════════════ x=0 y=1 j=-2

B entered with: -1
A entered with: -1
B entered with: -1
A entered with: -1
══════════════════════════════ x=1 y=1 j=-1

B entered with: 0
A entered with: 0
B entered with: 0
A entered with: 0
B entered with: 0
══════════════════════════════ x=0 y=0 j=0

B entered with: 1
A entered with: 1
B entered with: 1
A entered with: 1
══════════════════════════════ x=0 y=1 j=1

B entered with: 2
A entered with: 2
B entered with: 2
A entered with: 2
B entered with: 2
══════════════════════════════ x=0 y=0 j=2
</pre>

=={{header|Ring}}==
<syntaxhighlight lang="ring">
# Project : Short-circuit evaluation

for k = 1 to 2
word = ["AND","OR"]
see "========= " + word[k] + " ==============" + nl
for i = 0 to 1
for j = 0 to 1
see "a(" + i + ") " + word[k] +" b(" + j + ")" + nl
res =a(i)
if word[k] = "AND" and res != 0
res = b(j)
ok
if word[k] = "OR" and res = 0
res = b(j)
ok
next
next
next
func a(t)
see char(9) + "calls func a" + nl
a = t
return a
func b(t)
see char(9) + "calls func b" + nl
b = t
return b
</syntaxhighlight>
Output:
<pre>
========= AND ==============
a(0) AND b(0)
calls func a
a(0) AND b(1)
calls func a
a(1) AND b(0)
calls func a
calls func b
a(1) AND b(1)
calls func a
calls func b
========= OR ==============
a(0) OR b(0)
calls func a
calls func b
a(0) OR b(1)
calls func a
calls func b
a(1) OR b(0)
calls func a
a(1) OR b(1)
calls func a
</pre>

=={{header|Ruby}}==
Binary operators are short-circuiting. Demonstration code:
<syntaxhighlight lang="ruby">def a( bool )
puts "a( #{bool} ) called"
bool
end

def b( bool )
puts "b( #{bool} ) called"
bool
end

[true, false].each do |a_val|
[true, false].each do |b_val|
puts "a( #{a_val} ) and b( #{b_val} ) is #{a( a_val ) and b( b_val )}."
puts
puts "a( #{a_val} ) or b( #{b_val} ) is #{a( a_val) or b( b_val )}."
puts
end
end</syntaxhighlight>
{{out}}
<pre>
a( true ) called
b( true ) called
a( true ) and b( true ) is true.

a( true ) called
a( true ) or b( true ) is true.

a( true ) called
b( false ) called
a( true ) and b( false ) is false.

a( true ) called
a( true ) or b( false ) is true.

a( false ) called
a( false ) and b( true ) is false.

a( false ) called
b( true ) called
a( false ) or b( true ) is true.

a( false ) called
a( false ) and b( false ) is false.

a( false ) called
b( false ) called
a( false ) or b( false ) is false.
</pre>

=={{header|Run BASIC}}==
<syntaxhighlight lang="runbasic">for k = 1 to 2
ao$ = word$("AND,OR",k,",")
print "========= ";ao$;" =============="
for i = 0 to 1
for j = 0 to 1
print "a("; i; ") ";ao$;" b("; j; ")"
res =a(i) 'call always
'print res;"<===="
if ao$ = "AND" and res <> 0 then res = b(j)
if ao$ = "OR" and res = 0 then res = b(j)
next
next
next k
end

function a( t)
print chr$(9);"calls func a"
a = t
end function
function b( t)
print chr$(9);"calls func b"
b = t
end function</syntaxhighlight>
<pre>========= AND ==============
a(0) AND b(0)
calls func a
a(0) AND b(1)
calls func a
a(1) AND b(0)
calls func a
calls func b
a(1) AND b(1)
calls func a
calls func b
========= OR ==============
a(0) OR b(0)
calls func a
calls func b
a(0) OR b(1)
calls func a
calls func b
a(1) OR b(0)
calls func a
a(1) OR b(1)
calls func a</pre>

=={{header|Rust}}==

<syntaxhighlight lang="rust">fn a(foo: bool) -> bool {
println!("a");
foo
}

fn b(foo: bool) -> bool {
println!("b");
foo
}

fn main() {
for i in vec![true, false] {
for j in vec![true, false] {
println!("{} and {} == {}", i, j, a(i) && b(j));
println!("{} or {} == {}", i, j, a(i) || b(j));
println!();
}
}
}</syntaxhighlight>
{{out}}
<pre>
a
b
true and true == true
a
true or true == true

a
b
true and false == false
a
true or false == true

a
false and true == false
a
b
false or true == true

a
false and false == false
a
b
false or false == false
</pre>

=={{header|Sather}}==
<syntaxhighlight lang="sather">class MAIN is
a(v:BOOL):BOOL is
#OUT + "executing a\n";
return v;
end;
b(v:BOOL):BOOL is
#OUT + "executing b\n";
return v;
end;
main is
x:BOOL;

x := a(false) and b(true);
#OUT + "F and T = " + x + "\n\n";

x := a(true) or b(true);
#OUT + "T or T = " + x + "\n\n";

x := a(true) and b(false);
#OUT + "T and T = " + x + "\n\n";

x := a(false) or b(true);
#OUT + "F or T = " + x + "\n\n";
end;
end;</syntaxhighlight>

=={{header|Scala}}==
<syntaxhighlight lang="scala">object ShortCircuit {
def a(b:Boolean)={print("Called A=%5b".format(b));b}
def b(b:Boolean)={print(" -> B=%5b".format(b));b}

def main(args: Array[String]): Unit = {
val boolVals=List(false,true)
for(aa<-boolVals; bb<-boolVals){
print("\nTesting A=%5b AND B=%5b -> ".format(aa, bb))
a(aa) && b(bb)
}
for(aa<-boolVals; bb<-boolVals){
print("\nTesting A=%5b OR B=%5b -> ".format(aa, bb))
a(aa) || b(bb)
}
println
}
}</syntaxhighlight>
{{out}}
<pre>Testing A=false AND B=false -> Called A=false
Testing A=false AND B= true -> Called A=false
Testing A= true AND B=false -> Called A= true -> B=false
Testing A= true AND B= true -> Called A= true -> B= true
Testing A=false OR B=false -> Called A=false -> B=false
Testing A=false OR B= true -> Called A=false -> B= true
Testing A= true OR B=false -> Called A= true
Testing A= true OR B= true -> Called A= true</pre>


=={{header|Scheme}}==
=={{header|Scheme}}==
<lang scheme>>(define (a x)
<syntaxhighlight lang="scheme">>(define (a x)
(display "a\n")
(display "a\n")
x)
x)
Line 814: Line 4,341:
a
a
b
b
</syntaxhighlight>
</lang>


=={{header|SNOBOL4}}==
=={{header|Seed7}}==
<syntaxhighlight lang="seed7">$ include "seed7_05.s7i";
const func boolean: a (in boolean: aBool) is func
result
var boolean: result is FALSE;
begin
writeln("a");
result := aBool;
end func;
const func boolean: b (in boolean: aBool) is func
result
var boolean: result is FALSE;
begin
writeln("b");
result := aBool;
end func;
const proc: test (in boolean: param1, in boolean: param2) is func
begin
writeln(param1 <& " and " <& param2 <& " = " <& a(param1) and b(param2));
writeln(param1 <& " or " <& param2 <& " = " <& a(param1) or b(param2));
end func;
const proc: main is func
begin
test(FALSE, FALSE);
test(FALSE, TRUE);
test(TRUE, FALSE);
test(TRUE, TRUE);
end func;</syntaxhighlight>
{{out}}
<pre>
a
FALSE and FALSE = FALSE
a
b
FALSE or FALSE = FALSE
a
FALSE and TRUE = FALSE
a
b
FALSE or TRUE = TRUE
a
b
TRUE and FALSE = FALSE
a
TRUE or FALSE = TRUE
a
b
TRUE and TRUE = TRUE
a
TRUE or TRUE = TRUE
</pre>


=={{header|Sidef}}==
Because of its unique success/failure model of flow control, Snobol does not use standard boolean operators or assignment. However, in &fullscan mode Snobol exhibits short-circuit boolean behavior in pattern matches, with concatenation " " functioning as logical AND, and alternation " | " as logical OR.
<syntaxhighlight lang="ruby">func a(bool) { print 'A'; return bool }
func b(bool) { print 'B'; return bool }
 
# Test-driver
func test() {
for op in ['&&', '||'] {
for x,y in [[1,1],[1,0],[0,1],[0,0]] {
"a(%s) %s b(%s): ".printf(x, op, y)
eval "a(Bool(x)) #{op} b(Bool(y))"
print "\n"
}
}
}
 
# Test and display
test()</syntaxhighlight>
{{out}}
<pre>a(1) && b(1): AB
a(1) && b(0): AB
a(0) && b(1): A
a(0) && b(0): A
a(1) || b(1): A
a(1) || b(0): A
a(0) || b(1): AB
a(0) || b(0): AB</pre>


=={{header|Simula}}==
The test statements below use a pattern constructed from the functions a( ) and b( ) and match it to the null string with deferred evaluation. This idiom allows the functions to self-report the expected short-circuit patterns.
<syntaxhighlight lang="simula">BEGIN


BOOLEAN PROCEDURE A(BOOL); BOOLEAN BOOL;
<lang SNOBOL4> define('a(val)') :(a_end)
BEGIN OUTCHAR('A'); A := BOOL;
END A;

BOOLEAN PROCEDURE B(BOOL); BOOLEAN BOOL;
BEGIN OUTCHAR('B'); B := BOOL;
END B;

PROCEDURE OUTBOOL(BOOL); BOOLEAN BOOL;
OUTCHAR(IF BOOL THEN 'T' ELSE 'F');

PROCEDURE TEST;
BEGIN
PROCEDURE ANDTEST;
BEGIN
BOOLEAN X, Y, Z;
FOR X := TRUE, FALSE DO
FOR Y := TRUE, FALSE DO
BEGIN
OUTTEXT("A("); OUTBOOL(X);
OUTTEXT(") AND ");
OUTTEXT("B("); OUTBOOL(Y);
OUTTEXT("): ");
Z := A(X) AND THEN B(Y);
OUTIMAGE;
END;
END ANDTEST;

PROCEDURE ORTEST;
BEGIN
BOOLEAN X, Y, Z;
FOR X := TRUE, FALSE DO
FOR Y := TRUE, FALSE DO
BEGIN
OUTTEXT("A("); OUTBOOL(X);
OUTTEXT(") OR ");
OUTTEXT("B("); OUTBOOL(Y);
OUTTEXT("): ");
Z := A(X) OR ELSE B(Y);
OUTIMAGE;
END;
END ORTEST;

ANDTEST;
ORTEST;

END TEST;

TEST;
END.
</syntaxhighlight>
{{out}}
<pre>
A(T) AND B(T): AB
A(T) AND B(F): AB
A(F) AND B(T): A
A(F) AND B(F): A
A(T) OR B(T): A
A(T) OR B(F): A
A(F) OR B(T): AB
A(F) OR B(F): AB
</pre>

=={{header|Smalltalk}}==
{{works with|GNU Smalltalk}}
The <code>and:</code> <code>or:</code> selectors are shortcircuit selectors but in order to avoid evaluation of the second operand, it must be a block: <code>a and: [ code ]</code> will evaluate the code only if a is true. On the other hand, <code>a and: b</code>, where b is an expression (not a block), behaves like the non-shortcircuit and (&amp;). (Same speech for or |)
<syntaxhighlight lang="smalltalk">Smalltalk at: #a put: nil.
Smalltalk at: #b put: nil.

a := [:x| 'executing a' displayNl. x].
b := [:x| 'executing b' displayNl. x].

('false and false = %1' %
{ (a value: false) and: [ b value: false ] })
displayNl.

('true or false = %1' %
{ (a value: true) or: [ b value: false ] })
displayNl.

('false or true = %1' %
{ (a value: false) or: [ b value: true ] })
displayNl.

('true and false = %1' %
{ (a value: true) and: [ b value: false ] })
displayNl.</syntaxhighlight>

=={{header|SNOBOL4}}==
Because of its unique success/failure model of flow control, Snobol does not use standard boolean operators or assignment. However, in &amp;fullscan mode Snobol exhibits short-circuit boolean behavior in pattern matches, with concatenation " " functioning as logical AND, and alternation " | " as logical OR.

The test statements below use a pattern constructed from the functions a( ) and b( ) and match it to the null string with deferred evaluation. This idiom allows the functions to self-report the expected short-circuit patterns.
<syntaxhighlight lang="snobol4"> define('a(val)') :(a_end)
a out = 'A '
a out = 'A '
eq(val,1) :s(return)f(freturn)
eq(val,1) :s(return)f(freturn)
Line 847: Line 4,546:
out = 'F or T: '; null ? *a(0) | *b(1); nl()
out = 'F or T: '; null ? *a(0) | *b(1); nl()
out = 'F or F: '; null ? *a(0) | *b(0); nl()
out = 'F or F: '; null ? *a(0) | *b(0); nl()
end</lang>
end</syntaxhighlight>
{{out}}

Output:
<pre>T and T: A B
<pre>T and T: A B
T and F: A B
T and F: A B
Line 859: Line 4,557:
F or T: A B
F or T: A B
F or F: A B</pre>
F or F: A B</pre>

=={{header|Standard ML}}==
{{trans|OCaml}}
<syntaxhighlight lang="sml">fun a r = ( print " > function a called\n"; r )
fun b r = ( print " > function b called\n"; r )

fun test_and b1 b2 = (
print ("# testing (" ^ Bool.toString b1 ^ " andalso " ^ Bool.toString b2 ^ ")\n");
ignore (a b1 andalso b b2) )

fun test_or b1 b2 = (
print ("# testing (" ^ Bool.toString b1 ^ " orelse " ^ Bool.toString b2 ^ ")\n");
ignore (a b1 orelse b b2) )

fun test_this test = (
test true true;
test true false;
test false true;
test false false )
;

print "==== Testing and ====\n";
test_this test_and;
print "==== Testing or ====\n";
test_this test_or;</syntaxhighlight>
{{out}}
==== Testing and ====
# testing (true andalso true)
> function a called
> function b called
# testing (true andalso false)
> function a called
> function b called
# testing (false andalso true)
> function a called
# testing (false andalso false)
> function a called
==== Testing or ====
# testing (true orelse true)
> function a called
# testing (true orelse false)
> function a called
# testing (false orelse true)
> function a called
> function b called
# testing (false orelse false)
> function a called
> function b called

=={{header|Stata}}==

Stata always evaluates both arguments of operators & and |. Here is a solution with '''if''' statements.

<syntaxhighlight lang="stata">function a(x) {
printf(" a")
return(x)
}

function b(x) {
printf(" b")
return(x)
}

function call(i, j) {
printf("and:")
x = a(i)
if (x) {
x = b(j)
}
printf("\nor:")
y = a(i)
if (!y) {
y = b(j)
}
printf("\n")
return((x,y))
}</syntaxhighlight>

'''Example'''

<syntaxhighlight lang="stata">: call(0,1)
and: a
or: a b
1 2
+---------+
1 | 0 1 |
+---------+

: call(1,1)
and: a b
or: a
1 2
+---------+
1 | 1 1 |
+---------+</syntaxhighlight>

=={{header|Swift}}==
Short circuit operators are <nowiki>&&</nowiki> and ||.
<syntaxhighlight lang="swift">func a(v: Bool) -> Bool {
print("a")
return v
}

func b(v: Bool) -> Bool {
print("b")
return v
}

func test(i: Bool, j: Bool) {
println("Testing a(\(i)) && b(\(j))")
print("Trace: ")
println("\nResult: \(a(i) && b(j))")
println("Testing a(\(i)) || b(\(j))")
print("Trace: ")
println("\nResult: \(a(i) || b(j))")
println()
}

test(false, false)
test(false, true)
test(true, false)
test(true, true)</syntaxhighlight>
{{out}}
<pre>
Testing a(false) && b(false)
Trace: a
Result: false
Testing a(false) || b(false)
Trace: ab
Result: false

Testing a(false) && b(true)
Trace: a
Result: false
Testing a(false) || b(true)
Trace: ab
Result: true

Testing a(true) && b(false)
Trace: ab
Result: false
Testing a(true) || b(false)
Trace: a
Result: true

Testing a(true) && b(true)
Trace: ab
Result: true
Testing a(true) || b(true)
Trace: a
Result: true
</pre>


=={{header|Tcl}}==
=={{header|Tcl}}==
The <code>&&</code> and <code>||</code> in the <code>expr</code> command support short-circuit evaluation. It is recommended that you always put expressions in braces so that and command or variable substitutions are applied at the right time rather than before the expression is evaluated at all. (Indeed, it is recommended that you do that anyway as unbraced expressions cannot be efficiently compiled.)
The <code>&&</code> and <code>||</code> in the <code>expr</code> command support short-circuit evaluation. It is recommended that you always put expressions in braces so that and command or variable substitutions are applied at the right time rather than before the expression is evaluated at all. (Indeed, it is recommended that you do that anyway as unbraced expressions cannot be efficiently compiled.)
<lang tcl>package require Tcl 8.5
<syntaxhighlight lang="tcl">package require Tcl 8.5
proc tcl::mathfunc::a boolean {
proc tcl::mathfunc::a boolean {
puts "a($boolean) called"
puts "a($boolean) called"
Line 880: Line 4,732:
puts ""; # Blank line for clarity
puts ""; # Blank line for clarity
}
}
}</lang>
}</syntaxhighlight>
Output (note that booleans may be written out words or numeric):
{{out}}Note that booleans may be written out words or numeric:
<pre>
<pre>
a(false) called
a(false) called
Line 908: Line 4,760:


</pre>
</pre>

=={{header|TXR}}==
<syntaxhighlight lang="txr">@(define a (x out))
@ (output)
a (@x) called
@ (end)
@ (bind out x)
@(end)
@(define b (x out))
@ (output)
b (@x) called
@ (end)
@ (bind out x)
@(end)
@(define short_circuit_demo (i j))
@ (output)
a(@i) and b(@j):
@ (end)
@ (maybe)
@ (a i "1")
@ (b j "1")
@ (end)
@ (output)
a(@i) or b(@j):
@ (end)
@ (cases)
@ (a i "1")
@ (or)
@ (b j "1")
@ (or)
@ (accept)
@ (end)
@(end)
@(short_circuit_demo "0" "0")
@(short_circuit_demo "0" "1")
@(short_circuit_demo "1" "0")
@(short_circuit_demo "1" "1")</syntaxhighlight>
{{out|Run}}
<pre>$ txr short-circuit-bool.txr
a(0) and b(0):
a (0) called
a(0) or b(0):
a (0) called
b (0) called
a(0) and b(1):
a (0) called
a(0) or b(1):
a (0) called
b (1) called
a(1) and b(0):
a (1) called
b (0) called
a(1) or b(0):
a (1) called
a(1) and b(1):
a (1) called
b (1) called
a(1) or b(1):
a (1) called</pre>
The <code>a</code> and <code>b</code> functions are defined such that the second parameter is intended to be an unbound variable. When the function binds <code>out</code>, that value propagates back to the unbound variable at the call site. But the way calls works in this language allows us to specify a value instead such as <code>"1"</code>. So now the directive <code>@(bind out x)</code> performs unification instead: if <code>x</code> doesn't match <code>"1"</code>, the function fails, otherwise it succeeds.

So simply by placing two calls consecutively, we get a short circuting conjunction. The second will not execute if the first one fails.

Short-circuiting disjunction is provided by <code>@(cases)</code>.

The <code>@(maybe)</code> construct stops failure from propagating from the enclosed subquery. The <code>@(accept)</code> directive will bail out of the closest enclosing anonymous block (the function body) with a success. It prevents the <code>@(cases)</code> from failing the function if neither case is successful.

=={{header|UNIX Shell}}==
The ''&&'' and ''||'' operators use the exit status of each command. The ''true'' and ''false'' commands convert a string to an exit status; our code ''&& x=true || x=false'' converts an exit status to a string.
{{works with|Bourne Shell}}
<syntaxhighlight lang="bash">a() {
echo "Called a $1"
"$1"
}

b() {
echo "Called b $1"
"$1"
}

for i in false true; do
for j in false true; do
a $i && b $j && x=true || x=false
echo " $i && $j is $x"

a $i || b $j && y=true || y=false
echo " $i || $j is $y"
done
done</syntaxhighlight>
The output reveals that <nowiki>&&</nowiki> and || have short-circuit evaluation.
<pre>Called a false
false && false is false
Called a false
Called b false
false || false is false
Called a false
false && true is false
Called a false
Called b true
false || true is true
Called a true
Called b false
true && false is false
Called a true
true || false is true
Called a true
Called b true
true && true is true
Called a true
true || true is true</pre>

==={{header|C Shell}}===
Between commands, ''&&'' and ''||'' have short-circuit evaluation. (The aliases for ''a'' and ''b'' must expand to a single command; these aliases expand to an ''eval'' command.)
<syntaxhighlight lang="csh">alias a eval \''echo "Called a \!:1"; "\!:1"'\'
alias b eval \''echo "Called b \!:1"; "\!:1"'\'

foreach i (false true)
foreach j (false true)
a $i && b $j && set x=true || set x=false
echo " $i && $j is $x"

a $i || b $j && set x=true || set x=false
echo " $i || $j is $x"
end
end</syntaxhighlight>
Inside expressions, ''&&'' and ''||'' can short circuit some commands, but cannot prevent substitutions.
<syntaxhighlight lang="csh"># Succeeds, only prints "ok".
if ( 1 || { echo This command never runs. } ) echo ok

# Fails, aborts shell with "bad: Undefined variable".
if ( 1 || $bad ) echo ok

# Prints "error", then "ok".
if ( 1 || `echo error >/dev/stderr` ) echo ok</syntaxhighlight>

=={{header|VBA}}==
<syntaxhighlight lang="vb">Private Function a(i As Variant) As Boolean
Debug.Print "a: "; i = 1,
a = i
End Function
Private Function b(j As Variant) As Boolean
Debug.Print "b: "; j = 1;
b = j
End Function
Public Sub short_circuit()
Dim x As Boolean, y As Boolean
'Dim p As Boolean, q As Boolean
Debug.Print "=====AND=====" & vbCrLf
For p = 0 To 1
For q = 0 To 1
If a(p) Then
x = b(q)
End If
Debug.Print " = x"
Next q
Debug.Print
Next p
Debug.Print "======OR=====" & vbCrLf
For p = 0 To 1
For q = 0 To 1
If Not a(p) Then
x = b(q)
End If
Debug.Print " = x"
Next q
Debug.Print
Next p
Debug.Print
End Sub
</syntaxhighlight>{{out}}<pre>=====AND=====

a: Onwaar = x
a: Onwaar = x

a: Waar b: Onwaar = x
a: Waar b: Waar = x

======OR=====

a: Onwaar b: Onwaar = x
a: Onwaar b: Waar = x

a: Waar = x
a: Waar = x</pre>

=={{header|Visual Basic .NET}}==
{{trans|c++}}
<syntaxhighlight lang="vbnet">Module Module1

Function A(v As Boolean) As Boolean
Console.WriteLine("a")
Return v
End Function

Function B(v As Boolean) As Boolean
Console.WriteLine("b")
Return v
End Function

Sub Test(i As Boolean, j As Boolean)
Console.WriteLine("{0} and {1} = {2} (eager evaluation)", i, j, A(i) And B(j))
Console.WriteLine("{0} or {1} = {2} (eager evaluation)", i, j, A(i) Or B(j))
Console.WriteLine("{0} and {1} = {2} (lazy evaluation)", i, j, A(i) AndAlso B(j))
Console.WriteLine("{0} or {1} = {2} (lazy evaluation)", i, j, A(i) OrElse B(j))

Console.WriteLine()
End Sub

Sub Main()
Test(False, False)
Test(False, True)
Test(True, False)
Test(True, True)
End Sub

End Module</syntaxhighlight>
{{out}}
<pre>a
b
False and False = False (eager evaluation)
a
b
False or False = False (eager evaluation)
a
False and False = False (lazy evaluation)
a
b
False or False = False (lazy evaluation)

a
b
False and True = False (eager evaluation)
a
b
False or True = True (eager evaluation)
a
False and True = False (lazy evaluation)
a
b
False or True = True (lazy evaluation)

a
b
True and False = False (eager evaluation)
a
b
True or False = True (eager evaluation)
a
b
True and False = False (lazy evaluation)
a
True or False = True (lazy evaluation)

a
b
True and True = True (eager evaluation)
a
b
True or True = True (eager evaluation)
a
b
True and True = True (lazy evaluation)
a
True or True = True (lazy evaluation)</pre>

=={{header|Visual FoxPro}}==
<syntaxhighlight lang="vfp">
*!* Visual FoxPro natively supports short circuit evaluation
CLEAR
CREATE CURSOR funceval(arg1 L, arg2 L, operation V(3), result L, calls V(10))
*!* Conjunction
INSERT INTO funceval (arg1, arg2, operation) VALUES (.F., .F., "AND")
REPLACE result WITH (a(arg1) AND b(arg2))
INSERT INTO funceval (arg1, arg2, operation) VALUES (.F., .T., "AND")
REPLACE result WITH (a(arg1) AND b(arg2))
INSERT INTO funceval (arg1, arg2, operation) VALUES (.T., .F., "AND")
REPLACE result WITH (a(arg1) AND b(arg2))
INSERT INTO funceval (arg1, arg2, operation) VALUES (.T., .T., "AND")
REPLACE result WITH (a(arg1) AND b(arg2))
*!* Disjunction
INSERT INTO funceval (arg1, arg2, operation) VALUES (.F., .F., "OR")
REPLACE result WITH (a(arg1) OR b(arg2))
INSERT INTO funceval (arg1, arg2, operation) VALUES (.F., .T., "OR")
REPLACE result WITH (a(arg1) OR b(arg2))
INSERT INTO funceval (arg1, arg2, operation) VALUES (.T., .F., "OR")
REPLACE result WITH (a(arg1) OR b(arg2))
INSERT INTO funceval (arg1, arg2, operation) VALUES (.T., .T., "OR")
REPLACE result WITH (a(arg1) OR b(arg2))
GO TOP

_VFP.DataToClip("funceval", 8, 3)

FUNCTION a(v As Boolean) As Boolean
REPLACE calls WITH "a()"
RETURN v
ENDFUNC

FUNCTION b(v As Boolean) As Boolean
REPLACE calls WITH calls + ", b()"
RETURN v
ENDFUNC
</syntaxhighlight>
{{out}}
<pre>
Arg1 Arg2 Operation Result Calls
F F AND F a()
F T AND F a()
T F AND F a(), b()
T T AND T a(), b()
F F OR F a(), b()
F T OR T a(), b()
T F OR T a()
T T OR T a()
</pre>

=={{header|V (Vlang)}}==
<syntaxhighlight lang="Zig">
fn main() {
test_me(false, false)
test_me(false, true)
test_me(true, false)
test_me(true, true)
}

fn a(v bool) bool {
print("a")
return v
}

fn b(v bool) bool {
print("b")
return v
}

fn test_me(i bool, j bool) {
println("Testing a(${i}) && b(${j})")
print("Trace: ")
println("\nResult: ${a(i) && b(j)}")

println("Testing a(${i})} || b(${j})")
print("Trace: ")
println("\nResult: ${a(i) || b(j)}")
println("")
}
</syntaxhighlight>

{{out}}
<pre>
Testing a(false) && b(false)
Trace: a
Result: false
Testing a(false)} || b(false)
Trace: ab
Result: false

Testing a(false) && b(true)
Trace: a
Result: false
Testing a(false)} || b(true)
Trace: ab
Result: true

Testing a(true) && b(false)
Trace: ab
Result: false
Testing a(true)} || b(false)
Trace: a
Result: true

Testing a(true) && b(true)
Trace: ab
Result: true
Testing a(true)} || b(true)
Trace: a
Result: true
</pre>

=={{header|Wren}}==
Wren has the '''&&''' and '''||''' short-circuiting operators found in many C family languages.
<syntaxhighlight lang="wren">var a = Fn.new { |bool|
System.print(" a called")
return bool
}

var b = Fn.new { |bool|
System.print(" b called")
return bool
}

var bools = [ [true, true], [true, false], [false, true], [false, false] ]
for (bool in bools) {
System.print("a = %(bool[0]), b = %(bool[1]), op = && :")
a.call(bool[0]) && b.call(bool[1])
System.print()
}

for (bool in bools) {
System.print("a = %(bool[0]), b = %(bool[1]), op = || :")
a.call(bool[0]) || b.call(bool[1])
System.print()
}</syntaxhighlight>

{{out}}
<pre>
a = true, b = true, op = && :
a called
b called

a = true, b = false, op = && :
a called
b called

a = false, b = true, op = && :
a called

a = false, b = false, op = && :
a called

a = true, b = true, op = || :
a called

a = true, b = false, op = || :
a called

a = false, b = true, op = || :
a called
b called

a = false, b = false, op = || :
a called
b called
</pre>

=={{header|zkl}}==
<syntaxhighlight lang="zkl">fcn a(b){self.fcn.println(b); b}
fcn b(b){self.fcn.println(b); b}</syntaxhighlight>
{{out}}
<pre>
a(True) or b(True) //-->Fcn(a)True, True
a(False) or b(True) //-->Fcn(a)False, Fcn(b)True, True
a(False) or b(False) //-->Fcn(a)False, Fcn(b)False, False

a(True) and b(True) //-->Fcn(a)True, Fcn(b)True, True
a(True) and b(False) //-->Fcn(a)True, Fcn(b)False, False
a(False) and b(True) //-->Fcn(a)False, False
</pre>


{{omit from|GUISS}}
{{omit from|ZX Spectrum Basic|does not short circuit}}

Latest revision as of 15:39, 5 February 2024

Task
Short-circuit evaluation
You are encouraged to solve this task according to the task description, using any language you may know.
Control Structures

These are examples of control structures. You may also be interested in:


Assume functions   a   and   b   return boolean values,   and further, the execution of function   b   takes considerable resources without side effects, and is to be minimized.

If we needed to compute the conjunction   (and):

x = a() and b()

Then it would be best to not compute the value of   b()   if the value of   a()   is computed as   false,   as the value of   x   can then only ever be   false.

Similarly, if we needed to compute the disjunction (or):

y = a() or b()

Then it would be best to not compute the value of   b()   if the value of   a()   is computed as   true,   as the value of   y   can then only ever be   true.

Some languages will stop further computation of boolean equations as soon as the result is known, so-called   short-circuit evaluation   of boolean expressions


Task

Create two functions named   a   and   b,   that take and return the same boolean value.

The functions should also print their name whenever they are called.

Calculate and assign the values of the following equations to a variable in such a way that function   b   is only called when necessary:

x = a(i) and b(j)
y = a(i) or b(j)


If the language does not have short-circuit evaluation, this might be achieved with nested     if     statements.

11l

Translation of: Python
F a(v)
   print(‘  ## Called function a(#.)’.format(v))
   R v

F b(v)
   print(‘  ## Called function b(#.)’.format(v))
   R v

L(i) (0B, 1B)
   L(j) (0B, 1B)
      print("\nCalculating: x = a(i) and b(j)")
      V x = a(i) & b(j)
      print(‘Calculating: y = a(i) or  b(j)’)
      V y = a(i) | b(j)
Output:

Calculating: x = a(i) and b(j)
  # Called function a(0B)
Calculating: y = a(i) or  b(j)
  # Called function a(0B)
  # Called function b(0B)

Calculating: x = a(i) and b(j)
  # Called function a(0B)
Calculating: y = a(i) or  b(j)
  # Called function a(0B)
  # Called function b(1B)

Calculating: x = a(i) and b(j)
  # Called function a(1B)
  # Called function b(0B)
Calculating: y = a(i) or  b(j)
  # Called function a(1B)

Calculating: x = a(i) and b(j)
  # Called function a(1B)
  # Called function b(1B)
Calculating: y = a(i) or  b(j)
  # Called function a(1B)


6502 Assembly

There are no built-in booleans but the functionality can be easily implemented with 0 = False and 255 = True.

Source Code for the module:

;DEFINE 0 AS FALSE, $FF as true.
False equ 0
True equ 255
Func_A:
	;input: accumulator = value to check. 0 = false, nonzero = true.
	;output: 0 if false, 255 if true. Also prints the truth value to the screen.
	;USAGE: LDA val JSR Func_A
	BEQ .falsehood
	load16 z_HL,BoolText_A_True ;lda #<BoolText_A_True sta z_L lda #>BoolText_A_True sta z_H
	jsr PrintString
	jsr NewLine
	LDA #True
	rts
.falsehood:
	load16 z_HL,BoolText_A_False
	jsr PrintString
	jsr NewLine
	LDA #False
	rts
	
Func_B:
	;input: Y = value to check. 0 = false, nonzero = true.
	;output: 0 if false, 255 if true. Also prints the truth value to the screen.
	;USAGE: LDY val JSR Func_B
	TYA
	BEQ .falsehood	;return false
	load16 z_HL,BoolText_B_True
	jsr PrintString
	jsr NewLine
	LDA #True
	rts
.falsehood:
	load16 z_HL,BoolText_B_False
	jsr PrintString
	jsr NewLine
	LDA #False
	rts	


Func_A_and_B:
	;input: 
	;	z_B = input for Func_A
	;	z_C = input for Func_B
	;output:
		;0 if false, 255 if true
	LDA z_B
	jsr Func_A
	BEQ .falsehood
		LDY z_C
		jsr Func_B
		BEQ .falsehood
			;true
			load16 z_HL,BoolText_A_and_B_True
			jsr PrintString
			jsr NewLine
			LDA #True
			rts
.falsehood:
	load16 z_HL,BoolText_A_and_B_False
	jsr PrintString
	jsr NewLine
	LDA #False
	rts
	
Func_A_or_B:
	;input: 
	;	z_B = input for Func_A
	;	z_C = input for Func_B
	;output:
		;0 if false, 255 if true
	LDA z_B
	jsr Func_A
	BNE .truth
		LDY z_C
		jsr Func_B
		BNE .truth
			;false
			load16 z_HL,BoolText_A_or_B_False
			jsr PrintString
			LDA #False
			rts
.truth:
	load16 z_HL,BoolText_A_or_B_True
	jsr PrintString
	LDA #True
	rts
	
	
BoolText_A_True:
	db "A IS TRUE",0
BoolText_A_False:
	db "A IS FALSE",0
BoolText_B_True:
	db "B IS TRUE",0
BoolText_B_False:
	db "B IS FALSE",0
	
BoolText_A_and_B_True:
	db "A AND B IS TRUE",0
BoolText_A_and_B_False:
	db "A AND B IS FALSE",0
BoolText_A_or_B_True:
	db "A OR B IS TRUE",0
BoolText_A_or_B_False:
	db "A OR B IS FALSE",0


The relevant code for the actual invoking of the functions:

lda #True
sta z_B
lda #True
sta z_C
	
jsr Func_A_and_B
	
jsr NewLine
	
jsr Func_A_or_B
	
jmp *

And finally the output: [Output image]

Action!

BYTE FUNC a(BYTE x)
  PrintF(" a(%B)",x)
RETURN (x)

BYTE FUNC b(BYTE x)
  PrintF(" b(%B)",x)
RETURN (x)

PROC Main()
  BYTE i,j

  FOR i=0 TO 1
  DO
    FOR j=0 TO 1
    DO
      PrintF("Calculating %B AND %B: call",i,j)
      IF a(i)=1 AND b(j)=1 THEN
      FI
      PutE()
    OD
  OD
  PutE()

  FOR i=0 TO 1
  DO
    FOR j=0 TO 1
    DO
      PrintF("Calculating %B OR %B: call",i,j)
      IF a(i)=1 OR b(j)=1 THEN
      FI
      PutE()
    OD
  OD
RETURN
Output:

Screenshot from Atari 8-bit computer

Calculating 0 AND 0: call a(0)
Calculating 0 AND 1: call a(0)
Calculating 1 AND 0: call a(1) b(0)
Calculating 1 AND 1: call a(1) b(1)

Calculating 0 OR 0: call a(0) b(0)
Calculating 0 OR 1: call a(0) b(1)
Calculating 1 OR 0: call a(1)
Calculating 1 OR 1: call a(1)

Ada

Ada has built-in short-circuit operations and then and or else:

with Ada.Text_IO;  use Ada.Text_IO;

procedure Test_Short_Circuit is
   function A (Value : Boolean) return Boolean is
   begin
      Put (" A=" & Boolean'Image (Value));
      return Value;
   end A;
   function B (Value : Boolean) return Boolean is
   begin
      Put (" B=" & Boolean'Image (Value));
      return Value;
   end B;
begin
   for I in Boolean'Range loop
      for J in Boolean'Range loop
         Put (" (A and then B)=" & Boolean'Image (A (I) and then B (J)));
         New_Line;
      end loop;
   end loop;
   for I in Boolean'Range loop
      for J in Boolean'Range loop
         Put (" (A or else B)=" & Boolean'Image (A (I) or else B (J)));
         New_Line;
      end loop;
   end loop;
end Test_Short_Circuit;
Sample output:
 A=FALSE (A and then B)=FALSE
 A=FALSE (A and then B)=FALSE
 A=TRUE B=FALSE (A and then B)=FALSE
 A=TRUE B=TRUE (A and then B)=TRUE
 A=FALSE B=FALSE (A or else B)=FALSE
 A=FALSE B=TRUE (A or else B)=TRUE
 A=TRUE (A or else B)=TRUE
 A=TRUE (A or else B)=TRUE

ALGOL 68

With Standard

Works with: ALGOL 68 version Revision 1 - no extensions to language used
Works with: ALGOL 68G version Any - tested with release 1.18.0-9h.tiny
Works with: ELLA ALGOL 68 version Any (with appropriate job cards) - tested with release 1.8-8d

Note: The "brief" conditional clause ( ~ | ~ | ~ ) is a the standard's shorthand for enforcing short-circuit evaluation. Moreover, the coder is able to define their own proc[edures] and op[erators] that implement short-circuit evaluation by using Algol68's proceduring.

PRIO ORELSE = 2, ANDTHEN = 3; # user defined operators #
OP ORELSE =  (BOOL a, PROC BOOL b)BOOL: ( a | a | b ),
   ANDTHEN = (BOOL a, PROC BOOL b)BOOL: ( a | b | a );

# user defined Short-circuit_evaluation procedures #
PROC or else =  (BOOL a, PROC BOOL b)BOOL: ( a | a | b ),
     and then = (BOOL a, PROC BOOL b)BOOL: ( a | b | a );

test:(

  PROC a = (BOOL a)BOOL: ( print(("a=",a,", ")); a),
       b = (BOOL b)BOOL: ( print(("b=",b,", ")); b);

CO 
# Valid for Algol 68 Rev0: using "user defined" operators #
# Note: here BOOL is being automatically "procedured" to PROC BOOL #
  print(("T ORELSE F = ", a(TRUE) ORELSE b(FALSE), new line));
  print(("F ANDTHEN T = ", a(FALSE) ANDTHEN b(TRUE), new line));

  print(("or else(T, F) = ", or else(a(TRUE), b(FALSE)), new line));
  print(("and then(F, T) = ", and then(a(FALSE), b(TRUE)), new line));
END CO

# Valid for Algol68 Rev1: using "user defined" operators #
# Note: BOOL must be manually "procedured" to PROC BOOL #
  print(("T ORELSE F = ",  a(TRUE) ORELSE  (BOOL:b(FALSE)), new line));
  print(("T ORELSE T = ",  a(TRUE) ORELSE  (BOOL:b(TRUE)), new line));

  print(("F ANDTHEN F = ", a(FALSE) ANDTHEN (BOOL:b(FALSE)), new line));
  print(("F ANDTHEN T = ", a(FALSE) ANDTHEN (BOOL:b(TRUE)), new line));

  print(("F ORELSE F = ",  a(FALSE) ORELSE  (BOOL:b(FALSE)), new line));
  print(("F ORELSE T = ",  a(FALSE) ORELSE  (BOOL:b(TRUE)), new line));

  print(("T ANDTHEN F = ", a(TRUE) ANDTHEN (BOOL:b(FALSE)), new line));
  print(("T ANDTHEN T = ", a(TRUE) ANDTHEN (BOOL:b(TRUE)), new line))

)
Output:
a=T, T ORELSE F = T
a=T, T ORELSE T = T
a=F, F ANDTHEN F = F
a=F, F ANDTHEN T = F
a=F, b=F, F ORELSE F = F
a=F, b=T, F ORELSE T = T
a=T, b=F, T ANDTHEN F = F
a=T, b=T, T ANDTHEN T = T

With Extensions

Works with: ALGOL 68G version Any - tested with release 1.18.0-9h.tiny
Works with: ELLA ALGOL 68 version Any (with appropriate job cards) - tested with release 1.8-8d
test:(

  PROC a = (BOOL a)BOOL: ( print(("a=",a,", ")); a),
       b = (BOOL b)BOOL: ( print(("b=",b,", ")); b);

# Valid for Algol 68G and 68RS using non standard operators #
  print(("T OREL F = ",  a(TRUE) OREL  b(FALSE), new line));
  print(("T OREL T = ",  a(TRUE) OREL  b(TRUE), new line));

  print(("F ANDTH F = ", a(FALSE) ANDTH b(FALSE), new line));
  print(("F ANDTH T = ", a(FALSE) ANDTH b(TRUE), new line));

  print(("F OREL F = ",  a(FALSE) OREL  b(FALSE), new line));
  print(("F OREL T = ",  a(FALSE) OREL  b(TRUE), new line));

  print(("T ANDTH F = ", a(TRUE) ANDTH b(FALSE), new line));
  print(("T ANDTH T = ", a(TRUE) ANDTH b(TRUE), new line))

CO;
# Valid for Algol 68G and 68C using non standard operators #
  print(("T ORF F = ", a(TRUE) ORF b(FALSE), new line));
  print(("F ANDF T = ", a(FALSE) ANDF b(TRUE), new line))
END CO

)
Output:
a=T, T OREL F = T
a=T, T OREL T = T
a=F, F ANDTH F = F
a=F, F ANDTH T = F
a=F, b=F, F OREL F = F
a=F, b=T, F OREL T = T
a=T, b=F, T ANDTH F = F
a=T, b=T, T ANDTH T = T

ALGOL W

In Algol W the boolean "and" and "or" operators are short circuit operators.

begin

    logical procedure a( logical value v ) ; begin write( "a: ", v ); v end ;
    logical procedure b( logical value v ) ; begin write( "b: ", v ); v end ;

    write( "and: ", a( true  ) and b( true ) );
    write( "---" );
    write( "or:  ", a( true  ) or  b( true ) );
    write( "---" );
    write( "and: ", a( false ) and b( true ) );
    write( "---" );
    write( "or:  ", a( false ) or  b( true ) );
    write( "---" );
 
end.
Output:
and: 
a:   true  
b:   true    true  
---
or:  
a:   true    true  
---
and: 
a:  false   false  
---
or:  
a:  false  
b:   true    true  
---

AppleScript

AppleScript's boolean operators are short-circuiting (as can be seen from the log below).

What AppleScript lacks, however, is a short-circuiting ternary operator like the e ? e2 : e3 of C, or a short-circuiting three-argument function like cond in Lisp. To get a similar effect in AppleScript, we have to delay evaluation on both sides, using a cond which returns a reference to one of two unapplied handlers, and composing the result with a separate apply function, to apply the selected handler function to its argument.

(As a statement, rather than an expression, the if ... then ... else structure does not compose – unlike cond or ? :, it can not be nested inside expressions)

on run
    
    map(test, {|and|, |or|})
    
end run

-- test :: ((Bool, Bool) -> Bool) -> (Bool, Bool, Bool, Bool)
on test(f)
    map(f, {{true, true}, {true, false}, {false, true}, {false, false}})
end test



-- |and| :: (Bool, Bool) -> Bool
on |and|(tuple)
    set {x, y} to tuple
    
    a(x) and b(y)
end |and|

-- |or| :: (Bool, Bool) -> Bool
on |or|(tuple)
    set {x, y} to tuple
    
    a(x) or b(y)
end |or|

-- a :: Bool -> Bool
on a(bool)
    log "a"
    return bool
end a

-- b :: Bool -> Bool
on b(bool)
    log "b"
    return bool
end b


-- map :: (a -> b) -> [a] -> [b]
on map(f, xs)
    script mf
        property lambda : f
    end script
    set lng to length of xs
    set lst to {}
    repeat with i from 1 to lng
        set end of lst to mf's lambda(item i of xs, i, xs)
    end repeat
    return lst
end map


Output:
Messages:
(*a*)
(*b*)
(*a*)
(*b*)
(*a*)
(*a*)
(*a*)
(*a*)
(*a*)
(*b*)
(*a*)
(*b*)
Result:
{{true, false, false, false}, {true, true, true, false}}

Arturo

a: function [v][
    print ["called function A with:" v]
    v
]

b: function [v][
    print ["called function B with:" v]
    v
]

loop @[true false] 'i ->
    loop @[true false] 'j ->
        print ["\tThe result of A(i) AND B(j) is:" and? -> a i -> b j]

print ""

loop @[true false] 'i ->
    loop @[true false] 'j ->
        print ["\tThe result of A(i) OR B(j) is:" or? -> a i -> b j]
Output:
called function A with: true 
called function B with: true 
	The result of A(i) AND B(j) is: true 
called function A with: true 
called function B with: false 
	The result of A(i) AND B(j) is: false 
called function A with: false 
	The result of A(i) AND B(j) is: false 
called function A with: false 
	The result of A(i) AND B(j) is: false 

called function A with: true 
	The result of A(i) OR B(j) is: true 
called function A with: true 
	The result of A(i) OR B(j) is: true 
called function A with: false 
called function B with: true 
	The result of A(i) OR B(j) is: true 
called function A with: false 
called function B with: false 
	The result of A(i) OR B(j) is: false

AutoHotkey

In AutoHotkey, the boolean operators, and, or, and ternaries, short-circuit:

i = 1
j = 1
x := a(i) and b(j)
y := a(i) or b(j)

a(p)
{
 MsgBox, a() was called with the parameter "%p%".
 Return, p
}

b(p)
{
 MsgBox, b() was called with the parameter "%p%".
 Return, p
}

AWK

Short-circuit evalation is done in logical AND (&&) and logical OR (||) operators:

#!/usr/bin/awk -f 
BEGIN {
	print (a(1) && b(1))
	print (a(1) || b(1))
	print (a(0) && b(1))
	print (a(0) || b(1))
}


function a(x) {
	print "  x:"x
	return x
}
function b(y) {
	print "  y:"y
	return y
}
Output:
  x:1
  y:1
1
  x:1
1
  x:0
0
  x:0
  y:1
1

Axe

TEST(0,0)
TEST(0,1)
TEST(1,0)
TEST(1,1)
Return

Lbl TEST
r₁→X
r₂→Y
Disp X▶Hex+3," and ",Y▶Hex+3," = ",(A(X)?B(Y))▶Hex+3,i
Disp X▶Hex+3," or  ",Y▶Hex+3," = ",(A(X)??B(Y))▶Hex+3,i
.Wait for keypress
getKeyʳ
Return

Lbl A
r₁
Return

Lbl B
r₁
Return

BASIC

BaCon

BaCon supports short-circuit evaluation.

' Short-circuit evaluation
FUNCTION a(f)
    PRINT "FUNCTION a"
    RETURN f
END FUNCTION

FUNCTION b(f)
    PRINT "FUNCTION b"
    RETURN f
END FUNCTION

PRINT "FALSE and TRUE"
x = a(FALSE) AND b(TRUE)
PRINT x

PRINT "TRUE and TRUE"
x = a(TRUE) AND b(TRUE)
PRINT x

PRINT "FALSE or FALSE"
y = a(FALSE) OR b(FALSE)
PRINT y

PRINT "TRUE or FALSE"
y = a(TRUE) OR b(FALSE)
PRINT y
Output:
prompt$ ./short-circuit
FALSE and TRUE
FUNCTION a
0
TRUE and TRUE
FUNCTION a
FUNCTION b
1
FALSE or FALSE
FUNCTION a
FUNCTION b
0
TRUE or FALSE
FUNCTION a
1

Batch File

Translation of: Liberty BASIC
%=== Batch Files have no booleans on if command, let alone short-circuit evaluation ===%
%=== I will instead use 1 as true and 0 as false. ===%

@echo off
setlocal enabledelayedexpansion
echo AND
for /l %%i in (0,1,1) do (
for /l %%j in (0,1,1) do (
		echo.a^(%%i^) AND b^(%%j^)
		call :a %%i
		set res=!bool_a!
		if not !res!==0 (
			call :b %%j
			set res=!bool_b!
		)
		echo.=^>	!res!
)
)

echo ---------------------------------
echo OR
for /l %%i in (0,1,1) do (
	for /l %%j in (0,1,1) do (
		echo a^(%%i^) OR b^(%%j^)
		call :a %%i
		set res=!bool_a!
		if !res!==0 (
			call :b %%j
			set res=!bool_b!
		)
		echo.=^>	!res!
	)
)
pause>nul
exit /b 0


::----------------------------------------
:a
echo.	calls func a
set bool_a=%1
goto :EOF

:b
echo.	calls func b
set bool_b=%1
goto :EOF
Output:
AND
a(0) AND b(0)
        calls func a
=>      0
a(0) AND b(1)
        calls func a
=>      0
a(1) AND b(0)
        calls func a
        calls func b
=>      0
a(1) AND b(1)
        calls func a
        calls func b
=>      1
---------------------------------
OR
a(0) OR b(0)
        calls func a
        calls func b
=>      0
a(0) OR b(1)
        calls func a
        calls func b
=>      1
a(1) OR b(0)
        calls func a
=>      1
a(1) OR b(1)
        calls func a
=>      1

BBC BASIC

Short-circuit operators aren't implemented directly, but short-circuit AND can be simulated using cascaded IFs. Short-circuit OR can be converted into a short-circuit AND using De Morgan's laws.

      REM TRUE is represented as -1, FALSE as 0
      FOR i% = TRUE TO FALSE
        FOR j% = TRUE TO FALSE
          PRINT "For x=a(";FNboolstring(i%);") AND b(";FNboolstring(j%);")"
          x% = FALSE
          REM Short-circuit AND can be simulated by cascaded IFs:
          IF FNa(i%) IF FNb(j%) THEN x%=TRUE
          PRINT "x is ";FNboolstring(x%)
          PRINT
          PRINT "For y=a(";FNboolstring(i%);") OR b(";FNboolstring(j%);")"
          y% = FALSE
          REM Short-circuit OR can be simulated by De Morgan's laws:
          IF NOTFNa(i%) IF NOTFNb(j%) ELSE y%=TRUE : REM Note ELSE without THEN
          PRINT "y is ";FNboolstring(y%)
          PRINT
        NEXT:NEXT
      END
      
      DEFFNa(bool%)
      PRINT "Function A used; ";
      =bool%
      
      DEFFNb(bool%)
      PRINT "Function B used; ";
      =bool%
      
      DEFFNboolstring(bool%)
      IF bool%=0 THEN ="FALSE" ELSE="TRUE"

This gives the results shown below:

For x=a(TRUE) AND b(TRUE)
Function A used; Function B used; x is TRUE

For y=a(TRUE) OR b(TRUE)
Function A used; y is TRUE

For x=a(TRUE) AND b(FALSE)
Function A used; Function B used; x is FALSE

For y=a(TRUE) OR b(FALSE)
Function A used; y is TRUE

For x=a(FALSE) AND b(TRUE)
Function A used; x is FALSE

For y=a(FALSE) OR b(TRUE)
Function A used; Function B used; y is TRUE

For x=a(FALSE) AND b(FALSE)
Function A used; x is FALSE

For y=a(FALSE) OR b(FALSE)
Function A used; Function B used; y is FALSE

Bracmat

Bracmat has no booleans. The closest thing is the success or failure of an expression. A function is not called if the argument fails, so we have to use a trick to pass 'failure' to a function. Here it is accomplished by an extra level of indirection: two == in the definition of 'false' (and 'true', for symmetry) and two !! when evaluating the argument in the functions a and b. The backtick is another hack. This prefix tells Bracmat to look the other way if the backticked expression fails and to continue as if the expression succeeded. A neater way is to introduce an extra OR operator. That solution would have obscured the core of the current task. Short-circuit evaluation is heavily used in Bracmat code. Although not required, it is a good habit to exclusively use AND (&) and OR (|) operators to separate expressions, as the code below exemplifies.

( (a=.out$"I'm a"&!!arg)
& (b=.out$"I'm b"&!!arg)
& (false==~)
& (true==)
& !false !true:?outer
&   whl
  ' ( !outer:%?x ?outer
    & !false !true:?inner
    &   whl
      ' ( !inner:%?y ?inner
        &   out
          $ ( Testing
              (!!x&true|false)
              AND
              (!!y&true|false)
            )
        & `(a$!x&b$!y)
        &   out
          $ ( Testing
              (!!x&true|false)
              OR
              (!!y&true|false)
            )
        & `(a$!x|b$!y)
        )
    )
& done
);

Output:

Testing false AND false
I'm a
Testing false OR false
I'm a
I'm b
Testing false AND true
I'm a
Testing false OR true
I'm a
I'm b
Testing true AND false
I'm a
I'm b
Testing true OR false
I'm a
Testing true AND true
I'm a
I'm b
Testing true OR true
I'm a

C

Boolean operators && and || are shortcircuit operators.

#include <stdio.h>
#include <stdbool.h>

bool a(bool in)
{
  printf("I am a\n");
  return in;
}

bool b(bool in)
{
  printf("I am b\n");
  return in;
}

#define TEST(X,Y,O)						\
  do {								\
    x = a(X) O b(Y);						\
    printf(#X " " #O " " #Y " = %s\n\n", x ? "true" : "false");	\
  } while(false);

int main()
{
  bool x;

  TEST(false, true, &&); // b is not evaluated
  TEST(true, false, ||); // b is not evaluated
  TEST(true, false, &&); // b is evaluated
  TEST(false, false, ||); // b is evaluated 

  return 0;
}

C#

using System;

class Program
{
    static bool a(bool value)
    {
        Console.WriteLine("a");
        return value;
    }

    static bool b(bool value)
    {
        Console.WriteLine("b");
        return value;
    }

    static void Main()
    {
        foreach (var i in new[] { false, true })
        {
            foreach (var j in new[] { false, true })
            {
                Console.WriteLine("{0} and {1} = {2}", i, j, a(i) && b(j));
                Console.WriteLine();
                Console.WriteLine("{0} or {1} = {2}", i, j, a(i) || b(j));
                Console.WriteLine();
            }
        }
    }
}
Output:
a
False and False = False

a
b
False or False = False

a
False and True = False

a
b
False or True = True

a
b
True and False = False

a
True or False = True

a
b
True and True = True

a
True or True = True

C++

Just like C, boolean operators && and || are shortcircuit operators.

#include <iostream>

bool a(bool in)
{
    std::cout << "a" << std::endl;
    return in;
}

bool b(bool in)
{
    std::cout << "b" << std::endl;
    return in;
}

void test(bool i, bool j) {
    std::cout << std::boolalpha << i << " and " << j << " = " << (a(i) && b(j)) << std::endl;
    std::cout << std::boolalpha << i << " or " << j << " = " << (a(i) || b(j)) << std::endl;
}

int main()
{
    test(false, false);
    test(false, true);
    test(true, false);
    test(true, true);
    return 0;
}
Output:
a 
false and false = false
a 
b 
false or false = false
a 
false and true = false
a 
b 
false or true = true
a 
b 
true and false = false
a 
true or false = true
a 
b 
true and true = true
a 
true or true = true

Clojure

The print/println stuff in the doseq is kinda gross, but if you include them all in a single print, then the function traces are printed before the rest (since it has to evaluate them before calling print).

(letfn [(a [bool] (print "(a)") bool)   
        (b [bool] (print "(b)") bool)]  
  (doseq [i [true false] j [true false]]
    (print i "OR" j "= ")               
    (println (or (a i) (b j)))          
    (print i "AND" j " = ")             
    (println (and (a i) (b j)))))
Output:
true OR true = (a)true       
true AND true  = (a)(b)true  
true OR false = (a)true      
true AND false  = (a)(b)false
false OR true = (a)(b)true   
false AND true  = (a)false   
false OR false = (a)(b)false 
false AND false  = (a)false

Common Lisp

(defun a (F)
     (print 'a)
     F )

(defun b (F)
     (print 'b)
     F )

(dolist (x '((nil nil) (nil T) (T T) (T nil))) 
        (format t "~%(and ~S)" x) 
        (and (a (car x)) (b (car(cdr x)))) 
        (format t "~%(or ~S)" x) 
        (or (a (car x)) (b (car(cdr x)))))
Output:
(and (NIL NIL))
A 
(or (NIL NIL))
A 
B 
(and (NIL T))
A 
(or (NIL T))
A 
B 
(and (T T))
A 
B 
(or (T T))
A 
(and (T NIL))
A 
B 
(or (T NIL))
A

D

Translation of: Python
import std.stdio, std.algorithm;

T a(T)(T answer) {
    writefln("  # Called function a(%s) -> %s", answer, answer);
    return answer;
}

T b(T)(T answer) {
    writefln("  # Called function b(%s) -> %s", answer, answer);
    return answer;
}

void main() {
    foreach (immutable x, immutable y;
             [false, true].cartesianProduct([false, true])) {
        writeln("\nCalculating: r1 = a(x) && b(y)");
        immutable r1 = a(x) && b(y);
        writeln("Calculating: r2 = a(x) || b(y)");
        immutable r2 = a(x) || b(y);
    }
}
Output:
Calculating: r1 = a(x) && b(y)
  # Called function a(false) -> false
Calculating: r2 = a(x) || b(y)
  # Called function a(false) -> false
  # Called function b(false) -> false

Calculating: r1 = a(x) && b(y)
  # Called function a(true) -> true
  # Called function b(false) -> false
Calculating: r2 = a(x) || b(y)
  # Called function a(true) -> true

Calculating: r1 = a(x) && b(y)
  # Called function a(false) -> false
Calculating: r2 = a(x) || b(y)
  # Called function a(false) -> false
  # Called function b(true) -> true

Calculating: r1 = a(x) && b(y)
  # Called function a(true) -> true
  # Called function b(true) -> true
Calculating: r2 = a(x) || b(y)
  # Called function a(true) -> true

Delphi

Delphi supports short circuit evaluation by default. It can be turned off using the {$BOOLEVAL OFF} compiler directive.

program ShortCircuitEvaluation;

{$APPTYPE CONSOLE}

uses SysUtils;

function A(aValue: Boolean): Boolean;
begin
  Writeln('a');
  Result := aValue;
end;

function B(aValue: Boolean): Boolean;
begin
  Writeln('b');
  Result := aValue;
end;

var
  i, j: Boolean;
begin
  for i in [False, True] do
  begin
    for j in [False, True] do
    begin
      Writeln(Format('%s and %s = %s', [BoolToStr(i, True), BoolToStr(j, True), BoolToStr(A(i) and B(j), True)]));
      Writeln;
      Writeln(Format('%s or %s = %s', [BoolToStr(i, True), BoolToStr(j, True), BoolToStr(A(i) or B(j), True)]));
      Writeln;
    end;
  end;
end.

Dyalect

Translation of: Swift
func a(v) {
    print(nameof(a), terminator: "")
    return v
}
 
func b(v) {
    print(nameof(b), terminator: "")
    return v
}
 
func testMe(i, j) {
    print("Testing a(\(i)) && b(\(j))")
    print("Trace: ", terminator: "")
    print("\nResult: \(a(i) && b(j))")
 
    print("Testing a(\(i)) || b(\(j))")
    print("Trace: ", terminator: "")
    print("\nResult: \(a(i) || b(j))")
 
    print()
}
 
testMe(false, false)
testMe(false, true)
testMe(true, false)
testMe(true, true)
Output:
Testing a(false) && b(false)
Trace: a
Result: false
Testing a(false) || b(false)
Trace: ab
Result: false

Testing a(false) && b(true)
Trace: a
Result: false
Testing a(false) || b(true)
Trace: ab
Result: true

Testing a(true) && b(false)
Trace: ab
Result: false
Testing a(true) || b(false)
Trace: a
Result: true

Testing a(true) && b(true)
Trace: ab
Result: true
Testing a(true) || b(true)
Trace: a
Result: true

E

E defines && and || in the usual short-circuiting fashion.

def a(v) { println("a"); return v }
def b(v) { println("b"); return v }

def x := a(i) && b(j)
def y := b(i) || b(j)

Unusually, E is an expression-oriented language, and variable bindings (which are expressions) are in scope until the end of the nearest enclosing { ... } block. The combination of these features means that some semantics must be given to a binding occurring inside of a short-circuited alternative.

def x := a(i) && (def funky := b(j))

The choice we make is that funky is ordinary if the right-side expression was evaluated, and otherwise is ruined; attempts to access the variable give an error.

EasyLang

func a x .
   print "->a: " & x
   return x
.
func b x .
   print "->b: " & x
   return x
.
print "1 and 1"
if a 1 = 1 and b 1 = 1
   print "-> true"
.
print ""
print "1 or 1"
if a 1 = 1 or b 1 = 1
   print "-> true"
.
print ""
print "0 and 1"
if a 0 = 1 and b 1 = 1
   print "-> true"
.
print ""
print "0 or 1"
if a 0 = 1 or b 1 = 1
   print "-> true"
.

Ecstasy

Similar to Java, Ecstasy uses the  &&  and  ||  operators for short-circuiting logic, and  &  and  |  are the normal (non-short-circuiting) forms.

module test {
    @Inject Console console;

    static Boolean show(String name, Boolean value) {
        console.print($"{name}()={value}");
        return value;
    }

    void run() {
        val a = show("a", _);
        val b = show("b", _);

        for (Boolean v1 : False..True) {
            for (Boolean v2 : False..True) {
                console.print($"a({v1}) && b({v2}) == {a(v1) && b(v2)}");
                console.print();
                console.print($"a({v1}) || b({v2}) == {a(v1) || b(v2)}");
                console.print();
            }
        }
    }
}
Output:
a()=False
a(False) && b(False) == False

a()=False
b()=False
a(False) || b(False) == False

a()=False
a(False) && b(True) == False

a()=False
b()=True
a(False) || b(True) == True

a()=True
b()=False
a(True) && b(False) == False

a()=True
a(True) || b(False) == True

a()=True
b()=True
a(True) && b(True) == True

a()=True
a(True) || b(True) == True

Elena

ELENA 6.x :

import system'routines;
import extensions;
 
Func<bool, bool> a = (bool x){ console.writeLine("a"); ^ x };
 
Func<bool, bool> b = (bool x){ console.writeLine("b"); ^ x };
 
const bool[] boolValues = new bool[]{ false, true }; 
 
public program()
{
    boolValues.forEach::(bool i)
    {
        boolValues.forEach::(bool j)
        {
            console.printLine(i," and ",j," = ",a(i) && b(j));
 
            console.writeLine();
            console.printLine(i," or ",j," = ",a(i) || b(j));
            console.writeLine()
        }
    }
}
Output:
a
false and false = false

a
b
false or false = false

a
false and true = false

a
b
false or true = true

a
b
true and false = false

a
true or false = true

a
b
true and true = true

a
true or true = true

Elixir

defmodule Short_circuit do
  defp a(bool) do
    IO.puts "a( #{bool} ) called"
    bool
  end
  
  defp b(bool) do
    IO.puts "b( #{bool} ) called"
    bool
  end
  
  def task do
    Enum.each([true, false], fn i ->
      Enum.each([true, false], fn j ->
        IO.puts "a( #{i} ) and b( #{j} ) is #{a(i) and b(j)}.\n"
        IO.puts "a( #{i} ) or b( #{j} ) is #{a(i)  or b(j)}.\n"
      end)
    end)
  end
end

Short_circuit.task
Output:
a( true ) called
b( true ) called
a( true ) and b( true ) is true.

a( true ) called
a( true ) or b( true ) is true.

a( true ) called
b( false ) called
a( true ) and b( false ) is false.

a( true ) called
a( true ) or b( false ) is true.

a( false ) called
a( false ) and b( true ) is false.

a( false ) called
b( true ) called
a( false ) or b( true ) is true.

a( false ) called
a( false ) and b( false ) is false.

a( false ) called
b( false ) called
a( false ) or b( false ) is false.

Erlang

-module( short_circuit_evaluation ).

-export( [task/0] ).

task() ->
	[task_helper(X, Y) || X <- [true, false], Y <- [true, false]].



a( Boolean ) ->
	io:fwrite( " a ~p~n", [Boolean] ),
	Boolean.

b( Boolean ) ->
	io:fwrite( " b ~p~n", [Boolean] ),
	Boolean.

task_helper( Boolean1, Boolean2 ) ->
	io:fwrite( "~p andalso ~p~n", [Boolean1, Boolean2] ),
	io:fwrite( "=> ~p~n", [a(Boolean1) andalso b(Boolean2)] ),
	io:fwrite( "~p orelse ~p~n", [Boolean1, Boolean2] ),
	io:fwrite( "=> ~p~n", [a(Boolean1) orelse b(Boolean2)] ).
Output:
15> short_circuit_evaluation:task().
true andalso true
 a true
 b true
=> true
true orelse true
 a true
=> true
true andalso false
 a true
 b false
=> false
true orelse false
 a true
=> true
false andalso true
 a false
=> false
false orelse true
 a false
 b true
=> true
false andalso false
 a false
=> false
false orelse false
 a false
 b false
=> false

F#

let a (x : bool) = printf "(a)"; x
let b (x : bool) = printf "(b)"; x

[for x in [true; false] do for y in [true; false] do yield (x, y)]
|> List.iter (fun (x, y) ->
    printfn "%b AND %b = %b" x y ((a x) && (b y))
    printfn "%b OR %b = %b" x y ((a x) || (b y)))

Output

(a)(b)true AND true = true
(a)true OR true = true
(a)(b)true AND false = false
(a)true OR false = true
(a)false AND true = false
(a)(b)false OR true = true
(a)false AND false = false
(a)(b)false OR false = false

Factor

&& and || perform short-circuit evaluation, while and and or do not. && and || both expect a sequence of quotations to evaluate in a short-circuit manner. They are smart combinators; that is, they infer the number of arguments taken by the quotations. If you opt not to use the smart combinators, you can also use words like 0&& and 2|| where the arity of the quotations is dictated.

USING: combinators.short-circuit.smart io prettyprint ;
IN: rosetta-code.short-circuit

: a ( ? -- ? ) "(a)" write ;
: b ( ? -- ? ) "(b)" write ;

"f && f = " write { [ f a ] [ f b ] } && .
"f || f = " write { [ f a ] [ f b ] } || .
"f && t = " write { [ f a ] [ t b ] } && .
"f || t = " write { [ f a ] [ t b ] } || .
"t && f = " write { [ t a ] [ f b ] } && .
"t || f = " write { [ t a ] [ f b ] } || .
"t && t = " write { [ t a ] [ t b ] } && .
"t || t = " write { [ t a ] [ t b ] } || .
Output:
f && f = (a)f
f || f = (a)(b)f
f && t = (a)f
f || t = (a)(b)t
t && f = (a)(b)f
t || f = (a)t
t && t = (a)(b)t
t || t = (a)t

Fantom

class Main
{
  static Bool a (Bool value)
  {
    echo ("in a")
    return value
  }

  static Bool b (Bool value)
  {
    echo ("in b")
    return value
  }

  public static Void main ()
  {
    [false,true].each |i|
    {
      [false,true].each |j|
      {
        Bool result := a(i) && b(j)
        echo ("a($i) && b($j): " + result)
        result = a(i) || b(j)
        echo ("a($i) || b($j): " + result)
      }
    }
  }
}
Output:
in a
a(false) && b(false): false
in a
in b
a(false) || b(false): false
in a
a(false) && b(true): false
in a
in b
a(false) || b(true): true
in a
in b
a(true) && b(false): false
in a
a(true) || b(false): true
in a
in b
a(true) && b(true): true
in a
a(true) || b(true): true

Forth

\ Short-circuit evaluation definitions from Wil Baden, with minor name changes
:  ENDIF  postpone THEN ; immediate

:   COND  0 ; immediate
: ENDIFS  BEGIN DUP WHILE postpone ENDIF REPEAT DROP ; immediate
: ORELSE  s" ?DUP 0= IF"  evaluate ; immediate
:  ANDIF  s" DUP IF DROP" evaluate ; immediate
 
: .bool IF ." true  " ELSE ." false " THEN ;
: A  ." A=" DUP .bool ;
: B  ." B=" DUP .bool ;
 
: test
  CR
  1 -1 DO 1 -1 DO
    COND I A ANDIF  J B ENDIFS ." ANDIF="  .bool CR
    COND I A ORELSE J B ENDIFS ." ORELSE=" .bool CR
  LOOP LOOP ;

\ An alternative based on explicitly short-circuiting conditionals, Dave Keenan
: END-PRIOR-IF  1 CS-ROLL postpone ENDIF ; immediate

: test
  CR
  1 -1 DO 1 -1 DO
    I A    IF J B IF 1 ELSE END-PRIOR-IF 0 ENDIF ." ANDIF="  .bool CR
    I A 0= IF J B IF END-PRIOR-IF 1 ELSE 0 ENDIF ." ORELSE=" .bool CR
  LOOP LOOP ;
Output:
A=true  B=true  ANDIF=true
A=true  ORELSE=true
A=false ANDIF=false
A=false B=true  ORELSE=true
A=true  B=false ANDIF=false
A=true  ORELSE=true
A=false ANDIF=false
A=false B=false ORELSE=false

Fortran

Works with: Fortran version 90 and later

Using an IF .. THEN .. ELSE construct

program Short_Circuit_Eval
  implicit none

  logical :: x, y
  logical, dimension(2) :: l = (/ .false., .true. /)
  integer :: i, j

  do i = 1, 2
    do j = 1, 2
      write(*, "(a,l1,a,l1,a)") "Calculating x = a(", l(i), ") and b(", l(j), ")"   
      ! a AND b
      x = a(l(i))  
      if(x) then
        x = b(l(j))
        write(*, "(a,l1)") "x = ", x
      else
        write(*, "(a,l1)") "x = ", x
      end if
  
      write(*,*)
      write(*, "(a,l1,a,l1,a)") "Calculating y = a(", l(i), ") or b(", l(j), ")"   
      ! a OR b
      y = a(l(i))
      if(y) then
        write(*, "(a,l1)") "y = ", y
      else
        y = b(l(j))
        write(*, "(a,l1)") "y = ", y
      end if
      write(*,*)
    end do
  end do

contains

function a(value)
  logical :: a
  logical, intent(in) :: value

  a = value
  write(*, "(a,l1,a)") "Called function a(", value, ")"
end function

function b(value)
  logical :: b
  logical, intent(in) :: value
  
  b = value
  write(*, "(a,l1,a)") "Called function b(", value, ")"
end function
end program
Output:
Calculating x = a(F) and b(F)
Called function a(F)
x = F
 
Calculating y = a(F) or b(F)
Called function a(F)
Called function b(F)
y = F
 
Calculating x = a(F) and b(T)
Called function a(F)
x = F
 
Calculating y = a(F) or b(T)
Called function a(F)
Called function b(T)
y = T
 
Calculating x = a(T) and b(F)
Called function a(T)
Called function b(F)
x = F
 
Calculating y = a(T) or b(F)
Called function a(T)
y = T
 
Calculating x = a(T) and b(T)
Called function a(T)
Called function b(T)
x = T
 
Calculating y = a(T) or b(T)
Called function a(T)
y = T

FreeBASIC

' FB 1.05.0 Win64

Function a(p As Boolean) As Boolean
  Print "a() called"
  Return p
End Function

Function b(p As Boolean) As Boolean
  Print "b() called"
  Return p
End Function

Dim As Boolean i, j, x, y
i = False
j = True
Print "Without short-circuit evaluation :"
Print
x = a(i) And b(j)
y = a(i) Or b(j)
Print "x = "; x; " y = "; y
Print
Print "With short-circuit evaluation :"
Print
x = a(i) AndAlso b(j) '' b(j) not called as a(i) = false and so x must be false
y = a(i) OrElse b(j)  '' b(j) still called as can't determine y unless it is
Print "x = "; x; " y = "; y
Print
Print "Press any key to quit"
Sleep
Output:
Without short-circuit evaluation :

a() called
b() called
a() called
b() called
x = false y = true

With short-circuit evaluation :

a() called
a() called
b() called
x = false y = true

Fōrmulæ

Fōrmulæ programs are not textual, visualization/edition of programs is done showing/manipulating structures but not text. Moreover, there can be multiple visual representations of the same program. Even though it is possible to have textual representation —i.e. XML, JSON— they are intended for storage and transfer purposes more than visualization and edition.

Programs in Fōrmulæ are created/edited online in its website.

In this page you can see and run the program(s) related to this task and their results. You can also change either the programs or the parameters they are called with, for experimentation, but remember that these programs were created with the main purpose of showing a clear solution of the task, and they generally lack any kind of validation.

Solution

Go

Short circuit operators are && and ||.

package main

import "fmt"

func a(v bool) bool {
    fmt.Print("a")
    return v
}

func b(v bool) bool {
    fmt.Print("b")
    return v
}

func test(i, j bool) {
    fmt.Printf("Testing a(%t) && b(%t)\n", i, j)
    fmt.Print("Trace:  ")
    fmt.Println("\nResult:", a(i) && b(j))

    fmt.Printf("Testing a(%t) || b(%t)\n", i, j)
    fmt.Print("Trace:  ")
    fmt.Println("\nResult:", a(i) || b(j))

    fmt.Println("")
}

func main() {
    test(false, false)
    test(false, true)
    test(true, false)
    test(true, true)
}
Output:
Testing a(false) && b(false)
Trace:  a
Result: false
Testing a(false) || b(false)
Trace:  ab
Result: false

Testing a(false) && b(true)
Trace:  a
Result: false
Testing a(false) || b(true)
Trace:  ab
Result: true

Testing a(true) && b(false)
Trace:  ab
Result: false
Testing a(true) || b(false)
Trace:  a
Result: true

Testing a(true) && b(true)
Trace:  ab
Result: true
Testing a(true) || b(true)
Trace:  a
Result: true

Groovy

Like all C-based languages (of which I am aware), Groovy short-circuits the logical and (&&) and logical or (||) operations, but not the bitwise and (&) and bitwise or (|) operations.

def f = { println '  AHA!'; it instanceof String }
def g = { printf ('%5d ', it); it > 50 }

println 'bitwise'
assert g(100) & f('sss')
assert g(2) | f('sss')
assert ! (g(1) & f('sss'))
assert g(200) | f('sss')

println '''
logical'''
assert g(100) && f('sss')
assert g(2) || f('sss')
assert ! (g(1) && f('sss'))
assert g(200) || f('sss')
Output:
bitwise
  100   AHA!
    2   AHA!
    1   AHA!
  200   AHA!

logical
  100   AHA!
    2   AHA!
    1   200

Haskell

Lazy evaluation makes it possible for user-defined functions to be short-circuited. An expression will not be evaluated as long as it is not pattern matched:

module ShortCircuit where

import Prelude hiding ((&&), (||))
import Debug.Trace

False && _     = False
True  && False = False
_     && _     = True

True  || _     = True
False || True  = True
_     || _     = False

a p = trace ("<a " ++ show p ++ ">") p
b p = trace ("<b " ++ show p ++ ">") p

main = mapM_ print (    [ a p || b q | p <- [False, True], q <- [False, True] ]
                     ++ [ a p && b q | p <- [False, True], q <- [False, True] ])
Output:
<a False>
<b False>
False
<a False>
<b True>
True
<a True>
True
<a True>
True
<a False>
False
<a False>
False
<a True>
<b False>
False
<a True>
<b True>
True

One can force the right-hand arguemnt to be evaluated first be using the alternate definitions:

_     && False = False
False && True  = False
_     && _     = True

_     || True  = True
True  || False = True
_     || _     = False
Output:
<b False>
<a False>
False
<b True>
True
<b False>
<a True>
True
<b True>
True
<b False>
False
<b True>
<a False>
False
<b False>
False
<b True>
<a True>
True

The order of evaluation (in this case the original order again) can be seen in a more explicit form by desugaring the pattern matching:

p && q = case p of
           False -> False
           _     -> case q of
                      False -> False
                      _     -> True
                      
p || q = case p of
           True -> True
           _    -> case q of
                      True -> True
                      _    -> False

Icon and Unicon

The entire concept of using 'boolean' values for logic control runs counter to the philosophy of Icon. Instead Icon has success (something that returns a result) and failure which is really a signal. The concept is similar to that used in SNOBOL4 and Lisp and far more potent than passing around and testing booleans. There is no way to pass around a 'false' value in that sense. Icon does have facilities for dealing with bits inside integers but these would not normally be used for control purposes. Because failure is a signal control is always evaluated in a short-circuit manner. One consequence of this is that an expression "i < j" doesn't return a boolean value, instead it returns the value of j. While this may seem odd at first it allows for elegant expressions like "i < j < k". Another benefit is that there is no need for programmers to devote effort to staying inside the bounds of any data type. For instance, if you loop and iterate beyond bounds the expression simply fails and the loop ends.

While this task could be written literally, it would be more beneficial to show how an Icon programmer would approach the same problem. Icon extends the idea short circuit evaluation with the ability for expressions to generate alternate results only if needed. For more information see Failure is an option, Everything Returns a Value Except when it Doesn't, and Goal-Directed Evaluation and Generators. Consequently some small liberties will be taken with this task:

  • Since any result means an expression succeeded and is hence true, we can use any value. In this example our choice will be determined by how we deal with 'false'.
  • The inability to pass a 'false' value is a challenge. At first glance we might try &null, similar to Lisp, but there is no canonical true. Also &null produces a result, so strictly speaking it could be 'true' as well. A good example of this is that an expression like " not expr " returns null if 'expr' fails.
  • For this example we will define two procedures 'true' and 'false'. Because Icon treats procedures as a data type we can assign them and invoke them indirectly via the variable name they are assigned to. We can write " i := true " and later invoke 'true' via " i() ".
  • Rather than have the tasks print their own name, we will just utilize built-in tracing which will be more informative.

This use of procedures as values is somewhat contrived but serves us well for demonstration purposes. In practice this approach would be strained since failure results aren't re-captured as values (and can't easily be).

procedure main()
&trace := -1 # ensures functions print their names

every (i := false | true ) & ( j := false | true) do {
  write("i,j := ",image(i),", ",image(j))
  write("i & j:")
  x := i() & j()   # invoke true/false
  write("i | j:")
  y := i() | j()   # invoke true/false
  }
end

procedure true()   #: succeeds always (returning null)
return  
end

procedure false()  #: fails always
fail    # for clarity but not needed as running into end has the same effect
end

Sample output for a single case:

i,j := procedure true, procedure false
i & j:
Shortcircuit.icn:    8  | true()
Shortcircuit.icn:   16  | true returned &null
Shortcircuit.icn:    8  | false()
Shortcircuit.icn:   20  | false failed
i | j:
Shortcircuit.icn:   10  | true()
Shortcircuit.icn:   16  | true returned &null
i,j := procedure true, procedure true

Insitux

Translation of: Clojure
(let a (fn (print-str "a ") %)
     b (fn (print-str "b ") %)
     f (pad-right " " 6))

(for i [true false] j [true false]
  (print-str (f i) "OR  " (f j) " = ")
  (print (or (a i) (b j)))
  (print-str (f i) "AND " (f j) " = ")
  (print (and (a i) (b j))))
Output:
true  OR  true   = a true
true  AND true   = a b true
true  OR  false  = a true
true  AND false  = a b false
false OR  true   = a b true
false AND true   = a false
false OR  false  = a b false
false AND false  = a false

Io

Translation of: Ruby
a := method(bool,
    writeln("a(#{bool}) called." interpolate)
    bool
)
b := method(bool,
    writeln("b(#{bool}) called." interpolate)
    bool
)

list(true,false) foreach(avalue,
    list(true,false) foreach(bvalue,
        x := a(avalue) and b(bvalue)
        writeln("x = a(#{avalue}) and b(#{bvalue}) is #{x}" interpolate)
        writeln
        y := a(avalue) or b(bvalue)
        writeln("y = a(#{avalue}) or b(#{bvalue}) is #{y}" interpolate)
        writeln
    )
)
Output:
a(true) called.
b(true) called.
x = a(true) and b(true) is true

a(true) called.
y = a(true) or b(true) is true

a(true) called.
b(false) called.
x = a(true) and b(false) is false

a(true) called.
y = a(true) or b(false) is true

a(false) called.
x = a(false) and b(true) is false

a(false) called.
b(true) called.
y = a(false) or b(true) is true

a(false) called.
x = a(false) and b(false) is false

a(false) called.
b(false) called.
y = a(false) or b(false) is false

J

See the J wiki entry on short circuit booleans.

labeled=:1 :'[ smoutput@,&":~&m'
A=: 'A ' labeled
B=: 'B ' labeled
and=: ^:
or=: 2 :'u^:(-.@v)'
Example:
   (A and B) 1
B 1
A 1
1
   (A and B) 0
B 0
0
   (A or B) 1
B 1
1
   (A or B) 0
B 0
A 0
0

Note that J evaluates right-to-left.

Note also that both functions take the same argument (which might make this less than ideal for some purposes, but trying micromanage flow of control is usually counter-productive in J in much the way that global values can be counter-productive in an object oriented environment. When you are processing a large set of array data, flow of control can only make sense when it is relevant to all of the data being processed -- if you want to manage flow of control which is not relevant to the entire set of data being processed you might artificially reduce the amount of data being processed, along the lines of an SQL cursor).

Java

In Java the boolean operators && and || are short circuit operators. The eager operator counterparts are & and |.

public class ShortCirc {
    public static void main(String[] args){
        System.out.println("F and F = " + (a(false) && b(false)) + "\n");
        System.out.println("F or F = " + (a(false) || b(false)) + "\n");

        System.out.println("F and T = " + (a(false) && b(true)) + "\n");
        System.out.println("F or T = " + (a(false) || b(true)) + "\n");

        System.out.println("T and F = " + (a(true) && b(false)) + "\n");
        System.out.println("T or F = " + (a(true) || b(false)) + "\n");

        System.out.println("T and T = " + (a(true) && b(true)) + "\n");
        System.out.println("T or T = " + (a(true) || b(true)) + "\n");
    }

    public static boolean a(boolean a){
        System.out.println("a");
        return a;
    }

    public static boolean b(boolean b){
        System.out.println("b");
        return b;
    }
}
Output:
a
F and F = false

a
b
F or F = false

a
F and T = false

a
b
F or T = true

a
b
T and F = false

a
T or F = true

a
b
T and T = true

a
T or T = true

JavaScript

Short-circuiting evaluation of boolean expressions has been the default since the first versions of JavaScript.

(function () {
    'use strict';

    function a(bool) {
        console.log('a -->', bool);

        return bool;
    }

    function b(bool) {
        console.log('b -->', bool);

        return bool;
    }
  
  
    var x = a(false) && b(true),
        y = a(true) || b(false),
        z = true ? a(true) : b(false);
    
  return [x, y, z];
})();

The console log shows that in each case (the binding of all three values), only the left-hand part of the expression (the application of a(expr)) was evaluated – b(expr) was skipped by logical short-circuiting.

Output:

Console:

/* a --> false */
/* a --> true */
/* a --> true */

Return value:

[false, true, true]

jq

jq's 'and' and 'or' are short-circuit operators. The following demonstration, which follows the "awk" example above, requires a version of jq with the built-in filter 'stderr'.

def a(x): "  a(\(x))" | stderr | x;

def b(y): "  b(\(y))" | stderr | y;

"and:", (a(true) and b(true)),
"or:",  (a(true) or b(true)),
"and:", (a(false) and b(true)),
"or:",  (a(false) or b(true))
Output:
$ jq -r -n -f Short-circuit-evaluation.jq
and:
"  a(true)"
"  b(true)"
true
or:
"  a(true)"
true
and:
"  a(false)"
false
or:
"  a(false)"
"  b(true)"
true

Julia

Julia does have short-circuit evaluation, which works just as you expect it to:

a(x) = (println("\t# Called a($x)"); return x)
b(x) = (println("\t# Called b($x)"); return x)

for i in [true,false], j in [true, false]
    println("\nCalculating: x = a($i) && b($j)"); x = a(i) && b(j)
    println("\tResult: x = $x")
    println("\nCalculating: y = a($i) || b($j)"); y = a(i) || b(j)
    println("\tResult: y = $y")
end
Output:
Calculating: x = a(true) && b(true)
	# Called a(true)
	# Called b(true)
	Result: x = true

Calculating: y = a(true) || b(true)
	# Called a(true)
	Result: y = true

Calculating: x = a(true) && b(false)
	# Called a(true)
	# Called b(false)
	Result: x = false

Calculating: y = a(true) || b(false)
	# Called a(true)
	Result: y = true

Calculating: x = a(false) && b(true)
	# Called a(false)
	Result: x = false

Calculating: y = a(false) || b(true)
	# Called a(false)
	# Called b(true)
	Result: y = true

Calculating: x = a(false) && b(false)
	# Called a(false)
	Result: x = false

Calculating: y = a(false) || b(false)
	# Called a(false)
	# Called b(false)
	Result: y = false

Kotlin

// version 1.1.2

fun a(v: Boolean): Boolean {
    println("'a' called")
    return v
}

fun b(v: Boolean): Boolean {
    println("'b' called")
    return v
}

fun main(args: Array<String>){
    val pairs = arrayOf(Pair(true, true), Pair(true, false), Pair(false, true), Pair(false, false))
    for (pair in pairs) {
        val x = a(pair.first) && b(pair.second)
        println("${pair.first} && ${pair.second} = $x")
        val y = a(pair.first) || b(pair.second)
        println("${pair.first} || ${pair.second} = $y")
        println()
    }
}
Output:
'a' called
'b' called
true && true = true
'a' called
true || true = true

'a' called
'b' called
true && false = false
'a' called
true || false = true

'a' called
false && true = false
'a' called
'b' called
false || true = true

'a' called
false && false = false
'a' called
'b' called
false || false = false

Lambdatalk

Short-circuiting evaluation of boolean expressions has been the default since the first versions of lambdatalk.

{def A {lambda {:bool} :bool}}  -> A
{def B {lambda {:bool} :bool}}  -> B

{and {A true} {B true}}   -> true
{and {A true} {B false}}  -> false
{and {A false} {B true}}  -> false
{and {A false} {B false}} -> false

{or {A true} {B true}}    -> true
{or {A true} {B false}}   -> true
{or {A false} {B true}}   -> true
{or {A false} {B false}}  -> false

Some more words about short-circuit evaluation. Lambdatalk comes with the {if "bool" then "one" else "two"} special form where "one" or "two" are not evaluated until "bool" is. This behaviour prevents useless computing and allows recursive processes. For instance, the naïve fibonacci function quickly leads to extensive computings.

{def fib 
 {lambda {:n}
  {if {< :n 2}
   then 1 
   else {+ {fib {- :n 1}} {fib {- :n 2}}}}}}
-> fib

1) Using the if special form:

{if true then {+ 1 2} else {fib 29}}
-> 3              // {fib 29} is not evaluated

{if false then {+ 1 2} else {fib 29}}
-> 832040         // {fib 29} is evaluated in 5847ms

2) The if special form can't be simply replaced by a pair:

{def when {P.new {+ 1 2} {fib 29}}}  // inner expressions are
{P.left {when}}  -> 3                // both evaluated before
{P.right {when}} -> 832040           // and we don't want that

3) We can delay evaluation using lambdas:

{def when 
 {P.new {lambda {} {+ 1 2}}          // will return a lambda
        {lambda {} {fib 22}} }}      // to be evaluated later
-> when
{{P.left {when}}}  -> 3              // lambdas are evaluated
{{P.right {when}}} -> 832040         // after choice using {}

Liberty BASIC

LB does not have short-circuit evaluation. Implemented with IFs.

print "AND"
for i = 0 to 1
    for j = 0 to 1
        print "a("; i; ") AND b( "; j; ")"
        res =a( i)    'call always
        if res <>0 then  'short circuit if 0
            res = b( j)
        end if
        print "=>",res
    next
next

print "---------------------------------"
print "OR"
for i = 0 to 1
    for j = 0 to 1
        print "a("; i; ") OR b("; j; ")"
        res =a( i)    'call always
        if res = 0 then  'short circuit if <>0
            res = b( j)
        end if
        print "=>", res
    next
next

'----------------------------------------
function a( t)
    print ,"calls func a"
    a = t
end function

function b( t)
    print ,"calls func b"
    b = t
end function
Output:
AND
a(0) AND b( 0)
              calls func a
=>            0
a(0) AND b( 1)
              calls func a
=>            0
a(1) AND b( 0)
              calls func a
              calls func b
=>            0
a(1) AND b( 1)
              calls func a
              calls func b
=>            1
---------------------------------
OR
a(0) OR b(0)
              calls func a
              calls func b
=>            0
a(0) OR b(1)
              calls func a
              calls func b
=>            1
a(1) OR b(0)
              calls func a
=>            1
a(1) OR b(1)
              calls func a
=>            1

LiveCode

Livecode uses short-circuit evaluation.

global outcome
function a bool
    put "a called with" && bool & cr after outcome
    return bool
end a
function b bool
    put "b called with" && bool & cr after outcome
    return bool
end b

on mouseUp
    local tExp
    put empty into outcome
    repeat for each item op in "and,or"
        repeat for each item x in "true,false"
            put merge("a([[x]]) [[op]] b([[x]])") into tExp
            put merge(tExp && "is [[" & tExp & "]]") & cr after outcome
            put merge("a([[x]]) [[op]] b([[not x]])") into tExp
            put merge(tExp && "is [[" & tExp & "]]") & cr after outcome
        end repeat
        put cr after outcome
    end repeat
    put outcome
end mouseUp

The AND and OR predicates may take either expressions which are all evaluated beforehand, or lists which are short-circuit evaluated from left to right only until the overall value of the expression can be determined.

and [notequal? :x 0] [1/:x > 3]
(or [:x < 0] [:y < 0] [sqrt :x + sqrt :y <  3])

Lua

function a(i)
    print "Function a(i) called."
    return i
end

function b(i)
    print "Function b(i) called."
    return i
end

i = true
x = a(i) and b(i);  print ""
y = a(i) or  b(i);  print ""

i = false
x = a(i) and b(i);  print ""
y = a(i) or  b(i)

M2000 Interpreter

Module Short_circuit_evaluation {
	function a(a as boolean) {
		=a
		doc$<=format$("   Called function a({0}) -> {0}", a)+{
		}
	}
	function b(b as boolean) {
		=b
		doc$<=format$("   Called function b({0}) -> {0}", b)+{
		}
	}
	boolean T=true, F, iv, jv
	variant L=(F, T), i, j
	i=each(L)
	global doc$ : document doc$
	while i
		j=each(L)
		while j
			(iv, jv)=(array(i), array(j))
			doc$<=format$("Calculating x = a({0}) and b({1}) -> {2}", iv, jv, iv and jv)+{
			}
			x=if(a(iv)->b(jv), F)
			doc$<=format$("x={0}", x)+{
			}+ format$("Calculating y = a({0}) or b({1}) -> {2}", iv, jv, iv or jv)+{
			}
			y=if(a(iv)->T, b(jv))
			doc$<=format$("y={0}", y)+{
			
			}
		end while
	end while
	clipboard doc$
	report doc$
}
Short_circuit_evaluation
Output:
Calculating x = a(False) and b(False) -> False
   Called function a(False) -> False
x=False
Calculating y = a(False) or b(False) -> False
   Called function a(False) -> False
   Called function b(False) -> False
y=False

Calculating x = a(False) and b(True) -> False
   Called function a(False) -> False
x=False
Calculating y = a(False) or b(True) -> True
   Called function a(False) -> False
   Called function b(True) -> True
y=True

Calculating x = a(True) and b(False) -> False
   Called function a(True) -> True
   Called function b(False) -> False
x=False
Calculating y = a(True) or b(False) -> True
   Called function a(True) -> True
y=True

Calculating x = a(True) and b(True) -> True
   Called function a(True) -> True
   Called function b(True) -> True
x=True
Calculating y = a(True) or b(True) -> True
   Called function a(True) -> True
y=True

Maple

Built-in short circuit evaluation

a := proc(bool)
	printf("a is called->%s\n", bool):
	return bool:
end proc:
b := proc(bool)
	printf("b is called->%s\n", bool):
	return bool:
end proc:
for i in [true, false] do
	for j in [true, false] do
		printf("calculating	x := a(i) and b(j)\n"):
		x := a(i) and b(j):
		printf("calculating	x := a(i) or b(j)\n"):
		y := a(i) or  b(j):
	od:
od:
Output:
calculating	x := a(i) and b(j)
a is called->true
b is called->true
calculating	x := a(i) or b(j)
a is called->true
calculating	x := a(i) and b(j)
a is called->true
b is called->false
calculating	x := a(i) or b(j)
a is called->true
calculating	x := a(i) and b(j)
a is called->false
calculating	x := a(i) or b(j)
a is called->false
b is called->true
calculating	x := a(i) and b(j)
a is called->false
calculating	x := a(i) or b(j)
a is called->false
b is called->false

Mathematica/Wolfram Language

Mathematica has built-in short-circuit evaluation of logical expressions.

a[in_] := (Print["a"]; in)
b[in_] := (Print["b"]; in)
a[False] && b[True]
a[True] || b[False]

Evaluation of the preceding code gives:

a
False
a
True

Whereas evaluating this:

a[True] && b[False]

Gives:

a
b
False

MATLAB / Octave

Short-circuit evalation is done in logical AND (&&) and logical OR (||) operators:

  function x=a(x)
    printf('a: %i\n',x);	
  end; 
  function x=b(x)
    printf('b: %i\n',x);
  end; 

  a(1) && b(1)
  a(0) && b(1)
  a(1) || b(1)
  a(0) || b(1)
Output:
  > a(1) && b(1);
  a: 1
  b: 1
  > a(0) && b(1);
  a: 0
  > a(1) || b(1);
  a: 1
  > a(0) || b(1);
  a: 0
  b: 1

Modula-2

MODULE ShortCircuit;
FROM FormatString IMPORT FormatString;
FROM Terminal IMPORT WriteString,WriteLn,ReadChar;

PROCEDURE a(v : BOOLEAN) : BOOLEAN;
VAR buf : ARRAY[0..63] OF CHAR;
BEGIN
    FormatString("    # Called function a(%b)\n", buf, v);
    WriteString(buf);
    RETURN v
END a;

PROCEDURE b(v : BOOLEAN) : BOOLEAN;
VAR buf : ARRAY[0..63] OF CHAR;
BEGIN
    FormatString("    # Called function b(%b)\n", buf, v);
    WriteString(buf);
    RETURN v
END b;

PROCEDURE Print(x,y : BOOLEAN);
VAR buf : ARRAY[0..63] OF CHAR;
VAR temp : BOOLEAN;
BEGIN
    FormatString("a(%b) AND b(%b)\n", buf, x, y);
    WriteString(buf);
    temp := a(x) AND b(y);

    FormatString("a(%b) OR b(%b)\n", buf, x, y);
    WriteString(buf);
    temp := a(x) OR b(y);

    WriteLn;
END Print;

BEGIN
    Print(FALSE,FALSE);
    Print(FALSE,TRUE);
    Print(TRUE,TRUE);
    Print(TRUE,FALSE);
    ReadChar
END ShortCircuit.

MUMPS

MUMPS evaluates every expression it encounters, so we have to use conditional statements to do a short circuiting of the expensive second task.

SSEVAL1(IN)
 WRITE !,?10,$STACK($STACK,"PLACE")
 QUIT IN
SSEVAL2(IN)
 WRITE !,?10,$STACK($STACK,"PLACE")
 QUIT IN
SSEVAL3
 NEW Z
 WRITE "1 AND 1"
 SET Z=$$SSEVAL1(1) SET:Z Z=Z&$$SSEVAL2(1)
 WRITE !,$SELECT(Z:"TRUE",1:"FALSE")
 WRITE !!,"0 AND 1"
 SET Z=$$SSEVAL1(0) SET:Z Z=Z&$$SSEVAL2(1)
 WRITE !,$SELECT(Z:"TRUE",1:"FALSE")
 WRITE !!,"1 OR 1"
 SET Z=$$SSEVAL1(1) SET:'Z Z=Z!$$SSEVAL2(1)
 WRITE !,$SELECT(Z:"TRUE",1:"FALSE")
 WRITE !!,"0 OR 1"
 SET Z=$$SSEVAL1(0) SET:'Z Z=Z!$$SSEVAL2(1)
 WRITE !,$SELECT(Z:"TRUE",1:"FALSE")
 KILL Z
 QUIT
Output:
USER>D SSEVAL3^ROSETTA
1 AND 1
          SSEVAL1+1^ROSETTA +3
          SSEVAL2+1^ROSETTA +3
TRUE
 
0 AND 1
          SSEVAL1+1^ROSETTA +3
FALSE
 
1 OR 1
          SSEVAL1+1^ROSETTA +3
TRUE
 
0 OR 1
          SSEVAL1+1^ROSETTA +3
          SSEVAL2+1^ROSETTA +3
TRUE

Nanoquery

Nanoquery does not short-circuit by default, so short-circuit logic functions have been implemented by nested ifs.

def short_and(bool1, bool2)
    global a
    global b
    if a(bool1)
        if b(bool2)
            return true
        else
            return false
        end
    else
        return false
    end
end

def short_or(bool1, bool2)
    if a(bool1)
        return true
    else
        if b(bool2)
            return true
        else
            return false
        end
    end
end

def a(bool)
    println "a called."
    return bool
end

def b(bool)
    println "b called."
    return bool
end

println "F and F = " + short_and(false, false) + "\n"
println "F or F  = " + short_or(false, false)  + "\n"

println "F and T = " + short_and(false, true)  + "\n"
println "F or T  = " + short_or(false, true)   + "\n"

println "T and F = " + short_and(true, false)  + "\n"
println "T or F  = " + short_or(true, false)   + "\n"

println "T and T = " + short_and(true, true)   + "\n"
println "T or T  = " + short_or(true, true)    + "\n"
Output:
a called.
F and F = false

a called.
b called.
F or F  = false

a called.
F and T = false

a called.
b called.
F or T  = true

a called.
b called.
T and F = false

a called.
T or F  = true

a called.
b called.
T and T = true

a called.
T or T  = true

Nemerle

using System.Console;

class ShortCircuit
{
    public static a(x : bool) : bool
    {
        WriteLine("a");
        x
    }

    public static b(x : bool) : bool
    {
        WriteLine("b");
        x
    }
    
    public static Main() : void
    {
        def t = true;
        def f = false;

        WriteLine("True  && True : {0}", a(t) && b(t));
        WriteLine("True  && False: {0}", a(t) && b(f));
        WriteLine("False && True : {0}", a(f) && b(t));
        WriteLine("False && False: {0}", a(f) && b(f));
        WriteLine("True  || True : {0}", a(t) || b(t)); 
        WriteLine("True  || False: {0}", a(t) || b(f));
        WriteLine("False || True : {0}", a(f) || b(t));
        WriteLine("False || False: {0}", a(f) || b(f));   
    }
}
Output:
a
b
True  && True : True
a
b
True  && False: False
a
False && True : False
a
False && False: False
a
True  || True : True
a
True  || False: True
a
b
False || True : True
a
b
False || False: False

NetRexx

Translation of: ooRexx

Like OoRexx, NetRexx allows a list of expressions in the condition part of If and When. Evaluation ends with the first of these expressions resulting in boolean true.

/* NetRexx */
options replace format comments java crossref symbols nobinary

Parse Version v
Say 'Version='v

If a()  | b() Then Say 'a and b are true'
If \a() | b() Then Say 'Surprise'
Else               Say 'ok'

If a(),  b() Then Say 'a is true'
If \a(), b() Then Say 'Surprise'
Else              Say 'ok: \\a() is false'

Select
  When \a(), b() Then Say 'Surprise'
  Otherwise           Say 'ok: \\a() is false (Select)'
  End
Return

method a private static binary returns boolean
  state = Boolean.TRUE.booleanValue()
  Say '--a returns' state
  Return state

method b private static binary returns boolean
  state = Boolean.TRUE.booleanValue()
  Say '--b returns' state
  Return state
Output:
Version=NetRexx 3.03 11 Jun 2014
--a returns 1
--b returns 1
a and b are true
--a returns 1
--b returns 1
Surprise
--a returns 1
a is true
--a returns 1
--b returns 1
Surprise
--a returns 1
--b returns 1
Surprise

Nim

Nim produces code which uses short-circuit evaluation.

proc a(x): bool =
  echo "a called"
  result = x

proc b(x): bool =
  echo "b called"
  result = x

let x = a(false) and b(true) # echoes "a called"
let y = a(true) or b(true)   # echoes "a called"

Objeck

In Objeck the Boolean operators & and | short circuit.

class ShortCircuit {
  function : a(a : Bool) ~ Bool {
    "a"->PrintLine();
    return a;
  }

  function : b(b : Bool) ~ Bool {
    "b"->PrintLine();
    return b;
  }

  function : Main(args : String[]) ~ Nil {
    result := a(false) & b(false);
    "F and F = {$result}"->PrintLine();
    result := a(false) | b(false);
    "F or F = {$result}"->PrintLine();

    result := a(false) & b(true);
    "F and T = {$result}"->PrintLine();
    result := a(false) | b(true);
    "F or T = {$result}"->PrintLine();

    result := a(true) & b(false);
    "T and F = {$result}"->PrintLine();
    result := a(true) | b(false);
    "T or F = {$result}"->PrintLine();

    result := a(true) & b(true);
    "T and T = {$result}"->PrintLine();
    result := a(true) | b(true);
    "T or T = {$result}"->PrintLine();
  }
}

OCaml

let a r = print_endline " > function a called"; r
let b r = print_endline " > function b called"; r

let test_and b1 b2 =
  Printf.printf "# testing (%b && %b)\n" b1 b2;
  ignore (a b1 && b b2)

let test_or b1 b2 =
  Printf.printf "# testing (%b || %b)\n" b1 b2;
  ignore (a b1 || b b2)

let test_this test =
  test true true;
  test true false;
  test false true;
  test false false;
;;

let () =
  print_endline "==== Testing and ====";
  test_this test_and;
  print_endline "==== Testing or ====";
  test_this test_or;
;;
Output:
==== Testing and ====
# testing (true && true)
 > function a called
 > function b called
# testing (true && false)
 > function a called
 > function b called
# testing (false && true)
 > function a called
# testing (false && false)
 > function a called
==== Testing or ====
# testing (true || true)
 > function a called
# testing (true || false)
 > function a called
# testing (false || true)
 > function a called
 > function b called
# testing (false || false)
 > function a called
 > function b called

Ol

(define (a x)
   (print "   (a) => " x)
   x)

(define (b x)
   (print "   (b) => " x)
   x)

; and
(print " -- and -- ")
(for-each (lambda (x y)
      (print "let's evaluate '(a as " x ") and (b as " y ")':")
      (let ((out (and (a x) (b y))))
         (print "   result is " out)))
   '(#t #t #f #f)
   '(#t #f #t #f))

; or
(print " -- or -- ")
(for-each (lambda (x y)
      (print "let's evaluate '(a as " x ") or (b as " y ")':")
      (let ((out (or (a x) (b y))))
         (print "   result is " out)))
   '(#t #t #f #f)
   '(#t #f #t #f))
Output:
 -- and -- 
let's evaluate '(a as #true) and (b as #true)':
   (a) => #true
   (b) => #true
   result is #true
let's evaluate '(a as #true) and (b as #false)':
   (a) => #true
   (b) => #false
   result is #false
let's evaluate '(a as #false) and (b as #true)':
   (a) => #false
   result is #false
let's evaluate '(a as #false) and (b as #false)':
   (a) => #false
   result is #false
 -- or -- 
let's evaluate '(a as #true) or (b as #true)':
   (a) => #true
   result is #true
let's evaluate '(a as #true) or (b as #false)':
   (a) => #true
   result is #true
let's evaluate '(a as #false) or (b as #true)':
   (a) => #false
   (b) => #true
   result is #true
let's evaluate '(a as #false) or (b as #false)':
   (a) => #false
   (b) => #false
   result is #false

ooRexx

ooRexx allows a list of expressions in the condition part of If and When. Evaluation ends with the first of these expressions resulting in .false (or 0).

Parse Version v
Say 'Version='v
If a() | b() Then Say 'a and b are true'
If \a() | b() Then Say  'Surprise'
              Else Say 'ok'
If a(), b() Then Say 'a is true'
If \a(), b() Then Say  'Surprise'
             Else Say 'ok: \a() is false'
Select
  When \a(), b() Then Say 'Surprise'
  Otherwise           Say 'ok: \a() is false (Select)'
  End
Exit
a: Say 'a returns .true'; Return .true
b: Say 'b returns 1'; Return 1
Output:
Version=REXX-ooRexx_4.2.0(MT)_32-bit 6.04 22 Feb 2014
a returns .true
b returns 1
a and b are true
a returns .true
b returns 1
Surprise
a returns .true
b returns 1
a is true
a returns .true
ok: \a() is false
a returns .true
ok: \a() is false (Select)

Oz

Oz' andthen and orelse operators are short-circuiting, as indicated by their name. The library functions Bool.and and Bool.or are not short-circuiting, on the other hand.

declare
  fun {A Answer}
     AnswerS = {Value.toVirtualString Answer 1 1}
  in
     {System.showInfo "  % Called function {A "#AnswerS#"} -> "#AnswerS}
     Answer
  end

  fun {B Answer}
     AnswerS = {Value.toVirtualString Answer 1 1}
  in
     {System.showInfo "  % Called function {B "#AnswerS#"} -> "#AnswerS}
     Answer
  end
in
  for I in [false true] do
     for J in [false true] do
        X Y
     in
        {System.showInfo "\nCalculating: X = {A I} andthen {B J}"}
        X = {A I} andthen {B J}
        {System.showInfo "Calculating: Y = {A I} orelse {B J}"}
        Y = {A I} orelse {B J}
     end
  end
Output:
Calculating: X = {A I} andthen {B J}
  % Called function {A false} -> false
Calculating: Y = {A I} orelse {B J}
  % Called function {A false} -> false
  % Called function {B false} -> false

Calculating: X = {A I} andthen {B J}
  % Called function {A false} -> false
Calculating: Y = {A I} orelse {B J}
  % Called function {A false} -> false
  % Called function {B true} -> true

Calculating: X = {A I} andthen {B J}
  % Called function {A true} -> true
  % Called function {B false} -> false
Calculating: Y = {A I} orelse {B J}
  % Called function {A true} -> true

Calculating: X = {A I} andthen {B J}
  % Called function {A true} -> true
  % Called function {B true} -> true
Calculating: Y = {A I} orelse {B J}
  % Called function {A true} -> true

PARI/GP

Note that | and & are deprecated versions of the GP short-circuit operators.

a(n)={
  print(a"("n")");
  a
};
b(n)={
  print("b("n")");
  n
};
or(A,B)={
  a(A) || b(B)
};
and(A,B)={
  a(A) && b(B)
};

Pascal

Standard Pascal

Standard Pascal doesn't have native short-circuit evaluation.

program shortcircuit(output);

function a(value: boolean): boolean;
 begin
  writeln('a(', value, ')');
  a := value
 end;

function b(value:boolean): boolean;
 begin
  writeln('b(', value, ')');
  b := value
 end;

procedure scandor(value1, value2: boolean);
 var
  result: boolean;
 begin
  {and}
  if a(value1)
   then
    result := b(value2)
   else
    result := false;
  writeln(value1, ' and ', value2, ' = ', result);

  {or}
  if a(value1)
   then
    result := true
   else
    result := b(value2)
  writeln(value1, ' or ', value2, ' = ', result);
 end;

begin
 scandor(false, false);
 scandor(false, true);
 scandor(true, false);
 scandor(true, true);
end.

Turbo Pascal

Turbo Pascal allows short circuit evaluation with a compiler switch:

program shortcircuit;

function a(value: boolean): boolean;
 begin
  writeln('a(', value, ')');
  a := value;
 end;

function b(value:boolean): boolean;
 begin
  writeln('b(', value, ')');
  b := value;
 end;

{$B-} {enable short circuit evaluation}
procedure scandor(value1, value2: boolean);
 var
  result: boolean;
 begin
  result :=  a(value1) and b(value);
  writeln(value1, ' and ', value2, ' = ', result);

  result := a(value1) or b(value2);
  writeln(value1, ' or ', value2, ' = ', result);
 end;

begin
 scandor(false, false);
 scandor(false, true);
 scandor(true, false);
 scandor(true, true);
end.

Extended Pascal

The extended Pascal standard introduces the operators and_then and or_else for short-circuit evaluation.

program shortcircuit(output);

function a(value: boolean): boolean;
 begin
  writeln('a(', value, ')');
  a := value
 end;

function b(value:boolean): boolean;
 begin
  writeln('b(', value, ')');
  b := value
 end;

procedure scandor(value1, value2: boolean);
 var
  result: integer;
 begin
  result :=  a(value1) and_then b(value)
  writeln(value1, ' and ', value2, ' = ', result);

  result := a(value1) or_else b(value2);
  writeln(value1, ' or ', value2, ' = ', result)
 end;

begin
 scandor(false, false);
 scandor(false, true);
 scandor(true, false);
 scandor(true, true);
end.

Note: GNU Pascal allows and then and or else as alternatives to and_then and or_else.

Perl

Perl uses short-circuit boolean evaluation.

sub a { print 'A'; return $_[0] }
sub b { print 'B'; return $_[0] }

# Test-driver
sub test {
    for my $op ('&&','||') {
        for (qw(1,1 1,0 0,1 0,0)) {
           my ($x,$y) = /(.),(.)/;
           print my $str = "a($x) $op b($y)", ': ';
           eval $str; print "\n"; } }
}    

# Test and display
test();
Output:
a(1) && b(1): AB
a(1) && b(0): AB
a(0) && b(1): A
a(0) && b(0): A
a(1) || b(1): A
a(1) || b(0): A
a(0) || b(1): AB
a(0) || b(0): AB

Phix

In Phix all expressions are short circuited

with javascript_semantics
function a(integer i)
    printf(1,"a ")
    return i
end function
 
function b(integer i)
    printf(1,"b ")
    return i
end function
 
for z=0 to 1 do
    for i=0 to 1 do
        for j=0 to 1 do
            if z then
                printf(1,"a(%d) and b(%d) ",{i,j})
                printf(1," => %d\n",a(i) and b(j))
            else
                printf(1,"a(%d) or b(%d) ",{i,j})
                printf(1," => %d\n",a(i) or b(j))
            end if
        end for
    end for
end for
Output:
a(0) or b(0) a b  => 0
a(0) or b(1) a b  => 1
a(1) or b(0) a  => 1
a(1) or b(1) a  => 1
a(0) and b(0) a  => 0
a(0) and b(1) a  => 0
a(1) and b(0) a b  => 0
a(1) and b(1) a b  => 1

PicoLisp

(de a (F)
   (msg 'a)
   F )

(de b (F)
   (msg 'b)
   F )

(mapc
   '((I J)
      (for Op '(and or)
         (println I Op J '-> (Op (a I) (b J))) ) )
   '(NIL NIL T T)
   '(NIL T NIL T) )
Output:
a
NIL and NIL -> NIL
a
b
NIL or NIL -> NIL
a
NIL and T -> NIL
a
b
NIL or T -> T
a
b
T and NIL -> NIL
a
T or NIL -> T
a
b
T and T -> T
a
T or T -> T

Pike

int(0..1) a(int(0..1) i)
{
    write(" a\n");
    return i;
}

int(0..1) b(int(0..1) i)
{
    write(" b\n");
    return i;
}

foreach(({ ({ false, false }),  ({ false, true }), ({ true, true }), ({ true, false }) });; array(int) args)
{ 
    write(" %d && %d\n", @args); 
    a(args[0]) && b(args[1]);
 
    write(" %d || %d\n", @args); 
    a(args[0]) || b(args[1]);
}
Output:
 0 && 0
 a
 0 || 0
 a
 b
 0 && 1
 a
 0 || 1
 a
 b
 1 && 1
 a
 b
 1 || 1
 a
 1 && 0
 a
 b
 1 || 0
 a

PL/I

short_circuit_evaluation:
   procedure options (main);
   declare (true initial ('1'b), false initial ('0'b) ) bit (1);
   declare (i, j, x, y) bit (1);

a: procedure (bv) returns (bit(1));
   declare bv bit(1);
   put ('Procedure ' || procedurename() || ' called.');
   return (bv);
end a;
b: procedure (bv) returns (bit(1));
   declare bv bit(1);
   put ('Procedure ' || procedurename() || ' called.');
   return (bv);
end b;

   do i = true, false;
      do j = true, false;
         put skip(2) list ('Evaluating x with <a> with ' || i || ' and <b> with ' || j);
         put skip;
         if a(i) then
            x = b(j);
         else
             x = false;
         put skip data (x);
         put skip(2) list ('Evaluating y with <a> with ' || i || ' and <b> with ' || j);
         put skip;
         if a(i) then
            y = true;
         else
            y = b(j);
         put skip data (y);
      end;
   end;
end short_circuit_evaluation;
Results:
Evaluating x with <a> with 1 and <b> with 1 
Procedure A called.     Procedure B called. 
X='1'B;

Evaluating y with <a> with 1 and <b> with 1 
Procedure A called. 
Y='1'B;

Evaluating x with <a> with 1 and <b> with 0 
Procedure A called.     Procedure B called. 
X='0'B;

Evaluating y with <a> with 1 and <b> with 0 
Procedure A called. 
Y='1'B;

Evaluating x with <a> with 0 and <b> with 1 
Procedure A called. 
X='0'B;

Evaluating y with <a> with 0 and <b> with 1 
Procedure A called.     Procedure B called. 
Y='1'B;

Evaluating x with <a> with 0 and <b> with 0 
Procedure A called. 
X='0'B;

Evaluating y with <a> with 0 and <b> with 0 
Procedure A called.     Procedure B called. 
Y='0'B;

PowerShell

PowerShell handles this natively.

#  Simulated fast function
function a ( [boolean]$J ) { return $J }
 
#  Simulated slow function
function b ( [boolean]$J ) { Sleep -Seconds 2; return $J }
 
#  These all short-circuit and do not evaluate the right hand function
( a $True  ) -or  ( b $False )
( a $True  ) -or  ( b $True  )
( a $False ) -and ( b $False )
( a $False ) -and ( b $True  )
 
#  Measure of execution time
Measure-Command {
( a $True  ) -or  ( b $False )
( a $True  ) -or  ( b $True  )
( a $False ) -and ( b $False )
( a $False ) -and ( b $True  )
} | Select TotalMilliseconds
 
#  These all appropriately do evaluate the right hand function
( a $False ) -or  ( b $False )
( a $False ) -or  ( b $True  )
( a $True  ) -and ( b $False )
( a $True  ) -and ( b $True  )
 
#  Measure of execution time
Measure-Command {
( a $False ) -or  ( b $False )
( a $False ) -or  ( b $True  )
( a $True  ) -and ( b $False )
( a $True  ) -and ( b $True  )
} | Select TotalMilliseconds
Output:
True
True
False
False

TotalMilliseconds
-----------------
           15.653
False
True
False
True
        8012.9405

Prolog

Prolog has not functions but predicats succeed of fail. Tested with SWI-Prolog. Should work with other dialects.

short_circuit :-
	(   a_or_b(true, true) -> writeln('==> true'); writeln('==> false')) , nl,
	(   a_or_b(true, false)-> writeln('==>  true'); writeln('==> false')) , nl,
	(   a_or_b(false, true)-> writeln('==> true'); writeln('==> false')) , nl,
	(   a_or_b(false, false)-> writeln('==> true'); writeln('==> false')) , nl,
	(   a_and_b(true, true)-> writeln('==> true'); writeln('==> false')) , nl,
	(   a_and_b(true, false)-> writeln('==>  true'); writeln('==> false')) , nl,
	(   a_and_b(false, true)-> writeln('==>  true'); writeln('==> false')) , nl,
	(   a_and_b(false, false)-> writeln('==>  true'); writeln('==> false')) .


a_and_b(X, Y) :-
	format('a(~w) and b(~w)~n', [X, Y]),
	(   a(X), b(Y)).

a_or_b(X, Y) :-
	format('a(~w) or b(~w)~n', [X, Y]),
	(   a(X); b(Y)).

a(X) :-
	format('a(~w)~n', [X]),
	X.

b(X) :-
	format('b(~w)~n', [X]),
	X.
Output:
?- short_circuit.
a(true) or b(true)
a(true)
==> true

a(true) or b(false)
a(true)
==> true

a(false) or b(true)
a(false)
b(true)
==> true

a(false) or b(false)
a(false)
b(false)
==> false

a(true) and b(true)
a(true)
b(true)
==> true

a(true) and b(false)
a(true)
b(false)
==> false

a(false) and b(true)
a(false)
==> false

a(false) and b(false)
a(false)
==> false

true.

PureBasic

Logical And & Or operators will not evaluate their right-hand expression if the outcome can be determined from the value of the left-hand expression.

Procedure a(arg)
  PrintN("  # Called function a("+Str(arg)+")")  
  ProcedureReturn arg
EndProcedure

Procedure b(arg)
  PrintN("  # Called function b("+Str(arg)+")")
  ProcedureReturn arg
EndProcedure

OpenConsole()
For a=#False To #True
  For b=#False To #True
    PrintN(#CRLF$+"Calculating: x = a("+Str(a)+") And b("+Str(b)+")")
    x= a(a) And b(b)
    PrintN("Calculating: x = a("+Str(a)+") Or b("+Str(b)+")")
    y= a(a) Or b(b) 
  Next
Next
Input()
Output:
Calculating: x = a(0) And b(0)
  # Called function a(0)
Calculating: x = a(0) Or b(0)
  # Called function a(0)
  # Called function b(0)

Calculating: x = a(0) And b(1)
  # Called function a(0)
Calculating: x = a(0) Or b(1)
  # Called function a(0)
  # Called function b(1)

Calculating: x = a(1) And b(0)
  # Called function a(1)
  # Called function b(0)
Calculating: x = a(1) Or b(0)
  # Called function a(1)

Calculating: x = a(1) And b(1)
  # Called function a(1)
  # Called function b(1)
Calculating: x = a(1) Or b(1)
  # Called function a(1)

Python

Pythons and and or binary, infix, boolean operators will not evaluate their right-hand expression if the outcome can be determined from the value of the left-hand expression.

>>> def a(answer):
	print("  # Called function a(%r) -> %r" % (answer, answer))
	return answer

>>> def b(answer):
	print("  # Called function b(%r) -> %r" % (answer, answer))
	return answer

>>> for i in (False, True):
	for j in (False, True):
		print ("\nCalculating: x = a(i) and b(j)")
		x = a(i) and b(j)
		print ("Calculating: y = a(i) or  b(j)")
		y = a(i) or  b(j)

		

Calculating: x = a(i) and b(j)
  # Called function a(False) -> False
Calculating: y = a(i) or  b(j)
  # Called function a(False) -> False
  # Called function b(False) -> False

Calculating: x = a(i) and b(j)
  # Called function a(False) -> False
Calculating: y = a(i) or  b(j)
  # Called function a(False) -> False
  # Called function b(True) -> True

Calculating: x = a(i) and b(j)
  # Called function a(True) -> True
  # Called function b(False) -> False
Calculating: y = a(i) or  b(j)
  # Called function a(True) -> True

Calculating: x = a(i) and b(j)
  # Called function a(True) -> True
  # Called function b(True) -> True
Calculating: y = a(i) or  b(j)
  # Called function a(True) -> True

Pythons if expression can also be used to the same ends (but probably should not):

>>> for i in (False, True):
	for j in (False, True):
		print ("\nCalculating: x = a(i) and b(j) using x = b(j) if a(i) else False")
		x = b(j) if a(i) else False
		print ("Calculating: y = a(i) or  b(j) using y = b(j) if not a(i) else True")
		y = b(j) if not a(i) else True

		

Calculating: x = a(i) and b(j) using x = b(j) if a(i) else False
  # Called function a(False) -> False
Calculating: y = a(i) or  b(j) using y = b(j) if not a(i) else True
  # Called function a(False) -> False
  # Called function b(False) -> False

Calculating: x = a(i) and b(j) using x = b(j) if a(i) else False
  # Called function a(False) -> False
Calculating: y = a(i) or  b(j) using y = b(j) if not a(i) else True
  # Called function a(False) -> False
  # Called function b(True) -> True

Calculating: x = a(i) and b(j) using x = b(j) if a(i) else False
  # Called function a(True) -> True
  # Called function b(False) -> False
Calculating: y = a(i) or  b(j) using y = b(j) if not a(i) else True
  # Called function a(True) -> True

Calculating: x = a(i) and b(j) using x = b(j) if a(i) else False
  # Called function a(True) -> True
  # Called function b(True) -> True
Calculating: y = a(i) or  b(j) using y = b(j) if not a(i) else True
  # Called function a(True) -> True

Quackery

Quackery does not include short-circuit evaluation, but it can be added by use of meta-control flow words (words wrapped in reverse brackets such as ]done[.) For details see: The Book of Quackery

The short-circuit evaluation words SC-and and SC-or defined here are used thus: [ a 1 SC-and b ] and [ a 1 SC-or b ]. These presumes that the arguments to a and b are on the stack in the order j i.

The 1 preceding the word is required to indicate the number of arguments that b would consume from the stack if it were evaluated.

Extending the task to three functions, the third, c also consuming one argument k and returning a boolean, present on the stack underneath j and i would lead to the code [ a 2 SC-and b 1 SC-and c ] and [ a 2 SC-or b 1 SC-or c ], where the 2 is the sum of the number of arguments consumed by b and c, and the 1 is the number of arguments consumed by c.

SC-and and SC-or can both be used in a single short-circuit evaluation nest with three or more functions. Evaluation is strictly left to right.

Quackery does not have variables, so no assignment is shown here. Words (functions) leave their results on the stack. If desired results can be moved to ancillary stacks, which include standing-in for variables amongst their functionality.

  [ say "evaluating "
    ]this[ echo cr ]       is ident    (     -->   )

  [ iff say "true"
    else say "false" ]     is echobool (   b -->   )

  [ swap iff drop done
    times drop
    false ]done[ ]         is SC-and   ( b n -->   )

  [ swap not iff drop done
    times drop
    true ]done[ ]          is SC-or    ( b n -->   )

  [ ident
    2 times not ]          is a        (   b --> b )

  [ ident
    4 times not ]          is b        (   b --> b )

  [ say "i = "
    dup echobool
    say " AND j = "
    dup echobool
    cr
    [ a 1 SC-and b ]
    say "result is "
    echobool cr cr ]       is AND-demo (     -->   )

  [ say "i = "
    dup echobool
    say " OR j = "
    dup echobool
    cr
    [ a 1 SC-or b ]
    say "result is "
    echobool
    cr cr ]                is OR-demo  (     -->   )

  true  true  AND-demo
  true  false AND-demo
  false true  AND-demo
  false false AND-demo
  cr
  true  true  OR-demo
  true  false OR-demo
  false true  OR-demo
  false false OR-demo
Output:
i = true AND j = true
evaluating a
evaluating b
result is true

i = false AND j = false
evaluating a
result is false

i = true AND j = true
evaluating a
evaluating b
result is false

i = false AND j = false
evaluating a
result is false


i = true OR j = true
evaluating a
result is true

i = false OR j = false
evaluating a
evaluating b
result is true

i = true OR j = true
evaluating a
result is true

i = false OR j = false
evaluating a
evaluating b
result is false


R

The builtins && and || will short circuit:

Translation of: Perl
a <- function(x) {cat("a called\n"); x}
b <- function(x) {cat("b called\n"); x}

tests <- expand.grid(op=list(quote(`||`), quote(`&&`)), x=c(1,0), y=c(1,0))

invisible(apply(tests, 1, function(row) {
  call <- substitute(op(a(x),b(y)), row)
  cat(deparse(call), "->", eval(call), "\n\n")
}))
Output:
a called
a(1) || b(1) -> TRUE 

a called
b called
a(1) && b(1) -> TRUE 

a called
b called
a(0) || b(1) -> TRUE 

a called
a(0) && b(1) -> FALSE 

a called
a(1) || b(0) -> TRUE 

a called
b called
a(1) && b(0) -> FALSE 

a called
b called
a(0) || b(0) -> FALSE 

a called
a(0) && b(0) -> FALSE

Because R waits until function arguments are needed before evaluating them, user-defined functions can also short circuit.

switchop <- function(s, x, y) {
  if(s < 0) x || y
  else if (s > 0) x && y
  else xor(x, y)
}
Output:
> switchop(-1, a(1), b(1))
a called
[1] TRUE
> switchop(1, a(1), b(1))
a called
b called
[1] TRUE
> switchop(1, a(0), b(1))
a called
[1] FALSE
> switchop(0, a(0), b(1))
a called
b called
[1] TRUE

Racket

#lang racket
(define (a x)
  (display (~a "a:" x " "))
  x)

(define (b x)
  (display (~a "b:" x " "))
  x)

(for* ([x '(#t #f)]
       [y '(#t #f)])
  (displayln `(and (a ,x) (b ,y)))
  (and (a x) (b y)) 
  (newline)
  
  (displayln `(or (a ,x) (b ,y)))
  (or (a x) (b y))
  (newline))
Output:
(and (a #t) (b #t))
a:#t b:#t 
(or (a #t) (b #t))
a:#t 
(and (a #t) (b #f))
a:#t b:#f 
(or (a #t) (b #f))
a:#t 
(and (a #f) (b #t))
a:#f 
(or (a #f) (b #t))
a:#f b:#t 
(and (a #f) (b #f))
a:#f 
(or (a #f) (b #f))
a:#f b:#f 

Raku

(formerly Perl 6)

Works with: rakudo version 2018.03
use MONKEY-SEE-NO-EVAL;

sub a ($p) { print 'a'; $p }
sub b ($p) { print 'b'; $p }

for 1, 0 X 1, 0 -> ($p, $q) {
    for '&&', '||' -> $op {
        my $s = "a($p) $op b($q)";
        print "$s: ";
        EVAL $s;
        print "\n";
    }
}
Output:
a(1) && b(1): ab
a(1) || b(1): a
a(1) && b(0): ab
a(1) || b(0): a
a(0) && b(1): a
a(0) || b(1): ab
a(0) && b(0): a
a(0) || b(0): ab

REXX

The REXX language doesn't have native short circuits   (it's specifically mentioned in the language specifications that
short-circuiting is not supported).

/*REXX programs demonstrates short─circuit evaluation testing  (in an   IF   statement).*/
parse arg LO HI .                                /*obtain optional arguments from the CL*/
if LO=='' | LO==","  then LO= -2                 /*Not specified?  Then use the default.*/
if HI=='' | HI==","  then HI=  2                 /* "      "         "   "   "     "    */

         do j=LO  to HI                          /*process from the  low  to  the  high.*/
         x=a(j)  &  b(j)                         /*compute  function A  and  function B */
         y=a(j)  |  b(j)                         /*   "         "    "   or      "    " */
         if \y  then y=b(j)                      /*   "         "    B   (for negation).*/
         say  copies('═', 30)        '  x=' || x            '  y='y                '  j='j
         say
         end   /*j*/
exit                                             /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
a: say '      A  entered with:'  arg(1);    return abs( arg(1) // 2)   /*1=odd, 0=even  */
b: say '      B  entered with:'  arg(1);    return arg(1) < 0          /*1=neg, 0=if not*/
output   when using the default inputs:
      B  entered with: -2
      A  entered with: -2
      B  entered with: -2
      A  entered with: -2
══════════════════════════════   x=0   y=1   j=-2

      B  entered with: -1
      A  entered with: -1
      B  entered with: -1
      A  entered with: -1
══════════════════════════════   x=1   y=1   j=-1

      B  entered with: 0
      A  entered with: 0
      B  entered with: 0
      A  entered with: 0
      B  entered with: 0
══════════════════════════════   x=0   y=0   j=0

      B  entered with: 1
      A  entered with: 1
      B  entered with: 1
      A  entered with: 1
══════════════════════════════   x=0   y=1   j=1

      B  entered with: 2
      A  entered with: 2
      B  entered with: 2
      A  entered with: 2
      B  entered with: 2
══════════════════════════════   x=0   y=0   j=2

Ring

# Project : Short-circuit evaluation

for k = 1 to 2
      word = ["AND","OR"]
      see "========= " + word[k] + " ==============" + nl
      for i = 0 to 1
           for j = 0 to 1
                see "a(" + i + ") " + word[k] +" b(" + j + ")" + nl
                res =a(i)    
                if word[k] = "AND" and res != 0
                   res = b(j)
                ok
                if word[k] = "OR"  and res = 0 
                   res = b(j)
                ok
           next
      next
next
 
func a(t)
        see char(9) + "calls func a" + nl
        a = t
        return a
 
func b(t)
        see char(9) + "calls func b" + nl
        b = t
        return b

Output:

========= AND ==============
a(0) AND b(0)
	calls func a
a(0) AND b(1)
	calls func a
a(1) AND b(0)
	calls func a
	calls func b
a(1) AND b(1)
	calls func a
	calls func b
========= OR ==============
a(0) OR b(0)
	calls func a
	calls func b
a(0) OR b(1)
	calls func a
	calls func b
a(1) OR b(0)
	calls func a
a(1) OR b(1)
	calls func a

Ruby

Binary operators are short-circuiting. Demonstration code:

def a( bool )
  puts "a( #{bool} ) called"
  bool
end

def b( bool )
  puts "b( #{bool} ) called"
  bool
end

 [true, false].each do |a_val|
   [true, false].each do |b_val|
     puts "a( #{a_val} ) and b( #{b_val} ) is #{a( a_val ) and b( b_val )}."
     puts
     puts "a( #{a_val} ) or b( #{b_val} ) is #{a( a_val)  or b( b_val )}."
     puts
   end
 end
Output:
a( true ) called
b( true ) called
a( true ) and b( true ) is true.

a( true ) called
a( true ) or b( true ) is true.

a( true ) called
b( false ) called
a( true ) and b( false ) is false.

a( true ) called
a( true ) or b( false ) is true.

a( false ) called
a( false ) and b( true ) is false.

a( false ) called
b( true ) called
a( false ) or b( true ) is true.

a( false ) called
a( false ) and b( false ) is false.

a( false ) called
b( false ) called
a( false ) or b( false ) is false.

Run BASIC

for k = 1 to 2
ao$ = word$("AND,OR",k,",")
print "========= ";ao$;" =============="
for i = 0 to 1
    for j = 0 to 1
        print "a("; i; ") ";ao$;" b("; j; ")"
        res =a(i)    'call always
'print res;"<===="
if ao$ = "AND" and res <> 0 then res = b(j)
if ao$ = "OR"  and res =  0 then res = b(j)
    next
next
next k
end 

function a( t)
    print chr$(9);"calls func a"
    a = t
end function
 
function b( t)
    print chr$(9);"calls func b"
    b = t
end function
========= AND ==============
a(0) AND b(0)
	calls func a
a(0) AND b(1)
	calls func a
a(1) AND b(0)
	calls func a
	calls func b
a(1) AND b(1)
	calls func a
	calls func b
========= OR ==============
a(0) OR b(0)
	calls func a
	calls func b
a(0) OR b(1)
	calls func a
	calls func b
a(1) OR b(0)
	calls func a
a(1) OR b(1)
	calls func a

Rust

fn a(foo: bool) -> bool {
    println!("a");
    foo
}

fn b(foo: bool) -> bool {
    println!("b");
    foo
}

fn main() {
    for i in vec![true, false] {
        for j in vec![true, false] {
            println!("{} and {} == {}", i, j, a(i) && b(j));
            println!("{} or {} == {}", i, j, a(i) || b(j));
            println!();
        }
    }
}
Output:
a
b
true and true == true
a
true or true == true

a
b
true and false == false
a
true or false == true

a
false and true == false
a
b
false or true == true

a
false and false == false
a
b
false or false == false

Sather

class MAIN is
  a(v:BOOL):BOOL is 
    #OUT + "executing a\n";
    return v; 
  end;
  b(v:BOOL):BOOL is
    #OUT + "executing b\n";
    return v;
  end;
  
  main is
    x:BOOL;

    x := a(false) and b(true);
    #OUT + "F and T = " + x + "\n\n";

    x := a(true) or b(true);
    #OUT + "T or T = " + x + "\n\n";

    x := a(true) and b(false);
    #OUT + "T and T = " + x + "\n\n";

    x := a(false) or b(true);
    #OUT + "F or T = " + x + "\n\n";
  end;
end;

Scala

object ShortCircuit {
   def a(b:Boolean)={print("Called A=%5b".format(b));b}
   def b(b:Boolean)={print(" -> B=%5b".format(b));b}

   def main(args: Array[String]): Unit = {
      val boolVals=List(false,true)
      for(aa<-boolVals; bb<-boolVals){
         print("\nTesting A=%5b AND B=%5b   -> ".format(aa, bb))
         a(aa) && b(bb)
      }
      for(aa<-boolVals; bb<-boolVals){
         print("\nTesting A=%5b  OR B=%5b   -> ".format(aa, bb))
         a(aa) || b(bb)
      }
      println
   }
}
Output:
Testing A=false AND B=false   -> Called A=false
Testing A=false AND B= true   -> Called A=false
Testing A= true AND B=false   -> Called A= true -> B=false
Testing A= true AND B= true   -> Called A= true -> B= true
Testing A=false  OR B=false   -> Called A=false -> B=false
Testing A=false  OR B= true   -> Called A=false -> B= true
Testing A= true  OR B=false   -> Called A= true
Testing A= true  OR B= true   -> Called A= true

Scheme

>(define (a x)
   (display "a\n")
   x)
>(define (b x)
   (display "b\n")
   x)
>(for-each (lambda (i)
   (for-each (lambda (j)
     (display i) (display " and ") (display j) (newline)
     (and (a i) (b j))
     (display i) (display " or ") (display j) (newline)
     (or (a i) (b j))
    ) '(#t #f))
  ) '(#t #f))
#t and #t
a
b
#t or #t
a
#t and #f
a
b
#t or #f
a
#f and #t
a
#f or #t
a
b
#f and #f
a
#f or #f
a
b

Seed7

$ include "seed7_05.s7i";
 
const func boolean: a (in boolean: aBool) is func
  result
    var boolean: result is FALSE;
  begin
    writeln("a");
    result := aBool;
  end func;
 
const func boolean: b (in boolean: aBool) is func
  result
    var boolean: result is FALSE;
  begin
    writeln("b");
    result := aBool;
  end func;
 
const proc: test (in boolean: param1, in boolean: param2) is func
  begin
    writeln(param1 <& " and " <& param2 <& " = " <& a(param1) and b(param2));
    writeln(param1 <& " or " <& param2 <& " = " <& a(param1) or b(param2));
  end func;
 
const proc: main is func
  begin
    test(FALSE, FALSE);
    test(FALSE, TRUE);
    test(TRUE, FALSE);
    test(TRUE, TRUE);
  end func;
Output:
a
FALSE and FALSE = FALSE
a
b
FALSE or FALSE = FALSE
a
FALSE and TRUE = FALSE
a
b
FALSE or TRUE = TRUE
a
b
TRUE and FALSE = FALSE
a
TRUE or FALSE = TRUE
a
b
TRUE and TRUE = TRUE
a
TRUE or TRUE = TRUE

Sidef

func a(bool) { print 'A'; return bool }
func b(bool) { print 'B'; return bool }
 
# Test-driver
func test() {
    for op in ['&&', '||'] {
        for x,y in [[1,1],[1,0],[0,1],[0,0]] {
            "a(%s) %s b(%s): ".printf(x, op, y)
            eval "a(Bool(x)) #{op} b(Bool(y))"
            print "\n"
        }
    }
}
 
# Test and display
test()
Output:
a(1) && b(1): AB
a(1) && b(0): AB
a(0) && b(1): A
a(0) && b(0): A
a(1) || b(1): A
a(1) || b(0): A
a(0) || b(1): AB
a(0) || b(0): AB

Simula

BEGIN

    BOOLEAN PROCEDURE A(BOOL); BOOLEAN BOOL;
    BEGIN OUTCHAR('A'); A := BOOL;
    END A;

    BOOLEAN PROCEDURE B(BOOL); BOOLEAN BOOL;
    BEGIN OUTCHAR('B'); B := BOOL;
    END B;

    PROCEDURE OUTBOOL(BOOL); BOOLEAN BOOL;
        OUTCHAR(IF BOOL THEN 'T' ELSE 'F');

    PROCEDURE TEST;
    BEGIN
        PROCEDURE ANDTEST;
        BEGIN
            BOOLEAN X, Y, Z;
            FOR X := TRUE, FALSE DO
                FOR Y := TRUE, FALSE DO
                BEGIN
                    OUTTEXT("A("); OUTBOOL(X);
                    OUTTEXT(") AND ");
                    OUTTEXT("B("); OUTBOOL(Y);
                    OUTTEXT("): ");
                    Z := A(X) AND THEN B(Y);
                    OUTIMAGE;
                END;
        END ANDTEST;

        PROCEDURE ORTEST;
        BEGIN
            BOOLEAN X, Y, Z;
            FOR X := TRUE, FALSE DO
                FOR Y := TRUE, FALSE DO
                BEGIN
                    OUTTEXT("A("); OUTBOOL(X);
                    OUTTEXT(") OR ");
                    OUTTEXT("B("); OUTBOOL(Y);
                    OUTTEXT("): ");
                    Z := A(X) OR ELSE B(Y);
                    OUTIMAGE;
                END;
        END ORTEST;

        ANDTEST;
        ORTEST;

    END TEST;

    TEST;
END.
Output:
A(T) AND B(T): AB
A(T) AND B(F): AB
A(F) AND B(T): A
A(F) AND B(F): A
A(T) OR B(T): A
A(T) OR B(F): A
A(F) OR B(T): AB
A(F) OR B(F): AB

Smalltalk

Works with: GNU Smalltalk

The and: or: selectors are shortcircuit selectors but in order to avoid evaluation of the second operand, it must be a block: a and: [ code ] will evaluate the code only if a is true. On the other hand, a and: b, where b is an expression (not a block), behaves like the non-shortcircuit and (&). (Same speech for or |)

Smalltalk at: #a put: nil.
Smalltalk at: #b put: nil.

a := [:x| 'executing a' displayNl. x].
b := [:x| 'executing b' displayNl. x].

('false and false = %1' % 
  { (a value: false) and: [ b value: false ] })
    displayNl.

('true or false = %1' % 
  { (a value: true) or: [ b value: false ] })
    displayNl.

('false or true = %1' % 
  { (a value: false) or: [ b value: true ] })
    displayNl.

('true and false = %1' % 
  { (a value: true) and: [ b value: false ] })
    displayNl.

SNOBOL4

Because of its unique success/failure model of flow control, Snobol does not use standard boolean operators or assignment. However, in &fullscan mode Snobol exhibits short-circuit boolean behavior in pattern matches, with concatenation " " functioning as logical AND, and alternation " | " as logical OR.

The test statements below use a pattern constructed from the functions a( ) and b( ) and match it to the null string with deferred evaluation. This idiom allows the functions to self-report the expected short-circuit patterns.

        define('a(val)') :(a_end)
a       out = 'A '
        eq(val,1) :s(return)f(freturn)
a_end

        define('b(val)') :(b_end)
b       out = 'B '
        eq(val,1) :s(return)f(freturn)
b_end

*       # Test and display
        &fullscan = 1
        output(.out,1,'-[-r1]') ;* Macro Spitbol
*       output(.out,1,'B','-')  ;* CSnobol 
        define('nl()'):(nlx);nl output = :(return);nlx
 
        out = 'T and T: '; null ? *a(1) *b(1); nl()
        out = 'T and F: '; null ? *a(1) *b(0); nl() 
        out = 'F and T: '; null ? *a(0) *b(1); nl() 
        out = 'F and F: '; null ? *a(0) *b(0); nl() 
        output = 
        out = 'T or T: '; null ? *a(1) | *b(1); nl() 
        out = 'T or F: '; null ? *a(1) | *b(0); nl() 
        out = 'F or T: '; null ? *a(0) | *b(1); nl() 
        out = 'F or F: '; null ? *a(0) | *b(0); nl() 
end
Output:
T and T: A B
T and F: A B
F and T: A
F and F: A

T or T: A
T or F: A
F or T: A B
F or F: A B

Standard ML

Translation of: OCaml
fun a r = ( print " > function a called\n"; r )
fun b r = ( print " > function b called\n"; r )

fun test_and b1 b2 = (
  print ("# testing (" ^ Bool.toString b1 ^ " andalso " ^ Bool.toString b2 ^ ")\n");
  ignore (a b1 andalso b b2) )

fun test_or b1 b2 = (
  print ("# testing (" ^ Bool.toString b1 ^ " orelse " ^ Bool.toString b2 ^ ")\n");
  ignore (a b1 orelse b b2) )

fun test_this test = (
  test true true;
  test true false;
  test false true;
  test false false )
;

print "==== Testing and ====\n";
test_this test_and;
print "==== Testing or ====\n";
test_this test_or;
Output:
==== Testing and ====
# testing (true andalso true)
 > function a called
 > function b called
# testing (true andalso false)
 > function a called
 > function b called
# testing (false andalso true)
 > function a called
# testing (false andalso false)
 > function a called
==== Testing or ====
# testing (true orelse true)
 > function a called
# testing (true orelse false)
 > function a called
# testing (false orelse true)
 > function a called
 > function b called
# testing (false orelse false)
 > function a called
 > function b called

Stata

Stata always evaluates both arguments of operators & and |. Here is a solution with if statements.

function a(x) {
	printf(" a")
	return(x)
}

function b(x) {
	printf(" b")
	return(x)
}

function call(i, j) {
	printf("and:")
	x = a(i)
	if (x) {
		x = b(j)
	}
	printf("\nor:")
	y = a(i)
	if (!y) {
		y = b(j)
	}
	printf("\n")
	return((x,y))
}

Example

: call(0,1)
and: a
or: a b
       1   2
    +---------+
  1 |  0   1  |
    +---------+

: call(1,1)
and: a b
or: a
       1   2
    +---------+
  1 |  1   1  |
    +---------+

Swift

Short circuit operators are && and ||.

func a(v: Bool) -> Bool {
  print("a")
  return v
}

func b(v: Bool) -> Bool {
  print("b")
  return v
}

func test(i: Bool, j: Bool) {
  println("Testing a(\(i)) && b(\(j))")
  print("Trace:  ")
  println("\nResult: \(a(i) && b(j))")
  
  println("Testing a(\(i)) || b(\(j))")
  print("Trace:  ")
  println("\nResult: \(a(i) || b(j))")
  
  println()
}

test(false, false)
test(false, true)
test(true, false)
test(true, true)
Output:
Testing a(false) && b(false)
Trace:  a
Result: false
Testing a(false) || b(false)
Trace:  ab
Result: false

Testing a(false) && b(true)
Trace:  a
Result: false
Testing a(false) || b(true)
Trace:  ab
Result: true

Testing a(true) && b(false)
Trace:  ab
Result: false
Testing a(true) || b(false)
Trace:  a
Result: true

Testing a(true) && b(true)
Trace:  ab
Result: true
Testing a(true) || b(true)
Trace:  a
Result: true

Tcl

The && and || in the expr command support short-circuit evaluation. It is recommended that you always put expressions in braces so that and command or variable substitutions are applied at the right time rather than before the expression is evaluated at all. (Indeed, it is recommended that you do that anyway as unbraced expressions cannot be efficiently compiled.)

package require Tcl 8.5
proc tcl::mathfunc::a boolean {
    puts "a($boolean) called"
    return $boolean
}
proc tcl::mathfunc::b boolean {
    puts "b($boolean) called"
    return $boolean
}

foreach i {false true} {
    foreach j {false true} {
        set x [expr {a($i) && b($j)}]
        puts "x = a($i) && b($j) = $x"
        set y [expr {a($i) || b($j)}]
        puts "y = a($i) || b($j) = $y"
        puts ""; # Blank line for clarity
    }
}
Output:

Note that booleans may be written out words or numeric

a(false) called
x = a(false) && b(false) = 0
a(false) called
b(false) called
y = a(false) || b(false) = 0

a(false) called
x = a(false) && b(true) = 0
a(false) called
b(true) called
y = a(false) || b(true) = 1

a(true) called
b(false) called
x = a(true) && b(false) = 0
a(true) called
y = a(true) || b(false) = 1

a(true) called
b(true) called
x = a(true) && b(true) = 1
a(true) called
y = a(true) || b(true) = 1

TXR

@(define a (x out))
@  (output)
  a (@x) called
@  (end)
@  (bind out x)
@(end)
@(define b (x out))
@  (output)
  b (@x) called
@  (end)
@  (bind out x)
@(end)
@(define short_circuit_demo (i j))
@  (output)
a(@i) and b(@j):
@  (end)
@  (maybe)
@    (a i "1")
@    (b j "1")
@  (end)
@  (output)
a(@i) or b(@j):
@  (end)
@  (cases)
@    (a i "1")
@  (or)
@    (b j "1")
@  (or)
@    (accept)
@  (end)
@(end)
@(short_circuit_demo "0" "0")
@(short_circuit_demo "0" "1")
@(short_circuit_demo "1" "0")
@(short_circuit_demo "1" "1")
Run:
$ txr short-circuit-bool.txr 
a(0) and b(0):
  a (0) called
a(0) or b(0):
  a (0) called
  b (0) called
a(0) and b(1):
  a (0) called
a(0) or b(1):
  a (0) called
  b (1) called
a(1) and b(0):
  a (1) called
  b (0) called
a(1) or b(0):
  a (1) called
a(1) and b(1):
  a (1) called
  b (1) called
a(1) or b(1):
  a (1) called

The a and b functions are defined such that the second parameter is intended to be an unbound variable. When the function binds out, that value propagates back to the unbound variable at the call site. But the way calls works in this language allows us to specify a value instead such as "1". So now the directive @(bind out x) performs unification instead: if x doesn't match "1", the function fails, otherwise it succeeds.

So simply by placing two calls consecutively, we get a short circuting conjunction. The second will not execute if the first one fails.

Short-circuiting disjunction is provided by @(cases).

The @(maybe) construct stops failure from propagating from the enclosed subquery. The @(accept) directive will bail out of the closest enclosing anonymous block (the function body) with a success. It prevents the @(cases) from failing the function if neither case is successful.

UNIX Shell

The && and || operators use the exit status of each command. The true and false commands convert a string to an exit status; our code && x=true || x=false converts an exit status to a string.

Works with: Bourne Shell
a() {
	echo "Called a $1"
	"$1"
}

b() {
	echo "Called b $1"
	"$1"
}

for i in false true; do
	for j in false true; do
		a $i && b $j && x=true || x=false
		echo "  $i && $j is $x"

		a $i || b $j && y=true || y=false
		echo "  $i || $j is $y"
	done
done

The output reveals that && and || have short-circuit evaluation.

Called a false
  false && false is false
Called a false
Called b false
  false || false is false
Called a false
  false && true is false
Called a false
Called b true
  false || true is true
Called a true
Called b false
  true && false is false
Called a true
  true || false is true
Called a true
Called b true
  true && true is true
Called a true
  true || true is true

C Shell

Between commands, && and || have short-circuit evaluation. (The aliases for a and b must expand to a single command; these aliases expand to an eval command.)

alias a eval \''echo "Called a \!:1"; "\!:1"'\'
alias b eval \''echo "Called b \!:1"; "\!:1"'\'

foreach i (false true)
	foreach j (false true)
		a $i && b $j && set x=true || set x=false
		echo "  $i && $j is $x"

		a $i || b $j && set x=true || set x=false
		echo "  $i || $j is $x"
	end
end

Inside expressions, && and || can short circuit some commands, but cannot prevent substitutions.

# Succeeds, only prints "ok".
if ( 1 || { echo This command never runs. } ) echo ok

# Fails, aborts shell with "bad: Undefined variable".
if ( 1 || $bad ) echo ok

# Prints "error", then "ok".
if ( 1 || `echo error >/dev/stderr` ) echo ok

VBA

Private Function a(i As Variant) As Boolean
    Debug.Print "a:  "; i = 1,
    a = i
End Function
Private Function b(j As Variant) As Boolean
    Debug.Print "b: "; j = 1;
    b = j
End Function
Public Sub short_circuit()
    Dim x As Boolean, y As Boolean
    'Dim p As Boolean, q As Boolean
    Debug.Print "=====AND=====" & vbCrLf
    For p = 0 To 1
        For q = 0 To 1
            If a(p) Then
                x = b(q)
            End If
            Debug.Print " = x"
        Next q
        Debug.Print
    Next p
    Debug.Print "======OR=====" & vbCrLf
    For p = 0 To 1
        For q = 0 To 1
            If Not a(p) Then
                x = b(q)
            End If
            Debug.Print " = x"
        Next q
        Debug.Print
    Next p
    Debug.Print
End Sub
Output:
=====AND=====

a: Onwaar = x a: Onwaar = x

a: Waar b: Onwaar = x a: Waar b: Waar = x

======OR=====

a: Onwaar b: Onwaar = x a: Onwaar b: Waar = x

a: Waar = x

a: Waar = x

Visual Basic .NET

Translation of: c++
Module Module1

    Function A(v As Boolean) As Boolean
        Console.WriteLine("a")
        Return v
    End Function

    Function B(v As Boolean) As Boolean
        Console.WriteLine("b")
        Return v
    End Function

    Sub Test(i As Boolean, j As Boolean)
        Console.WriteLine("{0} and {1} = {2} (eager evaluation)", i, j, A(i) And B(j))
        Console.WriteLine("{0} or {1} = {2} (eager evaluation)", i, j, A(i) Or B(j))
        Console.WriteLine("{0} and {1} = {2} (lazy evaluation)", i, j, A(i) AndAlso B(j))
        Console.WriteLine("{0} or {1} = {2} (lazy evaluation)", i, j, A(i) OrElse B(j))

        Console.WriteLine()
    End Sub

    Sub Main()
        Test(False, False)
        Test(False, True)
        Test(True, False)
        Test(True, True)
    End Sub

End Module
Output:
a
b
False and False = False (eager evaluation)
a
b
False or False = False (eager evaluation)
a
False and False = False (lazy evaluation)
a
b
False or False = False (lazy evaluation)

a
b
False and True = False (eager evaluation)
a
b
False or True = True (eager evaluation)
a
False and True = False (lazy evaluation)
a
b
False or True = True (lazy evaluation)

a
b
True and False = False (eager evaluation)
a
b
True or False = True (eager evaluation)
a
b
True and False = False (lazy evaluation)
a
True or False = True (lazy evaluation)

a
b
True and True = True (eager evaluation)
a
b
True or True = True (eager evaluation)
a
b
True and True = True (lazy evaluation)
a
True or True = True (lazy evaluation)

Visual FoxPro

*!* Visual FoxPro natively supports short circuit evaluation
CLEAR
CREATE CURSOR funceval(arg1 L, arg2 L, operation V(3), result L, calls V(10))
*!* Conjunction
INSERT INTO funceval (arg1, arg2, operation) VALUES (.F., .F., "AND")
REPLACE result WITH (a(arg1) AND b(arg2))
INSERT INTO funceval (arg1, arg2, operation) VALUES (.F., .T., "AND")
REPLACE result WITH (a(arg1) AND b(arg2))
INSERT INTO funceval (arg1, arg2, operation) VALUES (.T., .F., "AND")
REPLACE result WITH (a(arg1) AND b(arg2))
INSERT INTO funceval (arg1, arg2, operation) VALUES (.T., .T., "AND")
REPLACE result WITH (a(arg1) AND b(arg2))
*!* Disjunction
INSERT INTO funceval (arg1, arg2, operation) VALUES (.F., .F., "OR")
REPLACE result WITH (a(arg1) OR b(arg2))
INSERT INTO funceval (arg1, arg2, operation) VALUES (.F., .T., "OR")
REPLACE result WITH (a(arg1) OR b(arg2))
INSERT INTO funceval (arg1, arg2, operation) VALUES (.T., .F., "OR")
REPLACE result WITH (a(arg1) OR b(arg2))
INSERT INTO funceval (arg1, arg2, operation) VALUES (.T., .T., "OR")
REPLACE result WITH (a(arg1) OR b(arg2))
GO TOP

_VFP.DataToClip("funceval", 8, 3)

FUNCTION a(v As Boolean) As Boolean
REPLACE calls WITH "a()"
RETURN v
ENDFUNC

FUNCTION b(v As Boolean) As Boolean
REPLACE calls WITH calls + ", b()"
RETURN v
ENDFUNC
Output:
Arg1	Arg2	Operation	Result	Calls     	
F   	F   	AND      	F     	a()       	
F   	T   	AND      	F     	a()       	
T   	F   	AND      	F     	a(), b()  	
T   	T   	AND      	T     	a(), b()  	
F   	F   	OR       	F     	a(), b()  	
F   	T   	OR       	T     	a(), b()  	
T   	F   	OR       	T     	a()       	
T   	T   	OR       	T     	a()       	

V (Vlang)

fn main() {
	test_me(false, false)
	test_me(false, true)
	test_me(true, false)
	test_me(true, true)
}

fn a(v bool) bool {
    print("a")
    return v
}

fn b(v bool) bool {
    print("b")
    return v
}

fn test_me(i bool, j bool) {
    println("Testing a(${i}) && b(${j})")
    print("Trace:  ")
    println("\nResult: ${a(i) && b(j)}")

    println("Testing a(${i})} || b(${j})")
    print("Trace:  ")
    println("\nResult: ${a(i) || b(j)}")
	println("")
}
Output:
Testing a(false) && b(false)
Trace:  a
Result: false
Testing a(false)} || b(false)
Trace:  ab
Result: false

Testing a(false) && b(true)
Trace:  a
Result: false
Testing a(false)} || b(true)
Trace:  ab
Result: true

Testing a(true) && b(false)
Trace:  ab
Result: false
Testing a(true)} || b(false)
Trace:  a
Result: true

Testing a(true) && b(true)
Trace:  ab
Result: true
Testing a(true)} || b(true)
Trace:  a
Result: true

Wren

Wren has the && and || short-circuiting operators found in many C family languages.

var a = Fn.new { |bool|
    System.print("  a called")
    return bool
}

var b = Fn.new { |bool| 
    System.print("  b called")
    return bool
}

var bools = [ [true, true], [true, false], [false, true], [false, false] ]
for (bool in bools) {
    System.print("a = %(bool[0]), b = %(bool[1]), op = && :")
    a.call(bool[0]) && b.call(bool[1])
    System.print()
}

for (bool in bools) {
    System.print("a = %(bool[0]), b = %(bool[1]), op = || :")
    a.call(bool[0]) || b.call(bool[1])
    System.print()
}
Output:
a = true, b = true, op = && :
  a called
  b called

a = true, b = false, op = && :
  a called
  b called

a = false, b = true, op = && :
  a called

a = false, b = false, op = && :
  a called

a = true, b = true, op = || :
  a called

a = true, b = false, op = || :
  a called

a = false, b = true, op = || :
  a called
  b called

a = false, b = false, op = || :
  a called
  b called

zkl

fcn a(b){self.fcn.println(b); b}
fcn b(b){self.fcn.println(b); b}
Output:
a(True)  or b(True)  //-->Fcn(a)True, True
a(False) or b(True)  //-->Fcn(a)False, Fcn(b)True, True
a(False) or b(False) //-->Fcn(a)False, Fcn(b)False, False

a(True)  and b(True)  //-->Fcn(a)True, Fcn(b)True, True
a(True)  and b(False) //-->Fcn(a)True, Fcn(b)False, False
a(False) and b(True)  //-->Fcn(a)False, False