Assertions in design by contract: Difference between revisions

Content added Content deleted
m (syntax highlighting fixup automation)
Line 14: Line 14:


You '''cannot''' read the break flag this way:
You '''cannot''' read the break flag this way:
<lang 6502asm>php ;NV-BDIZC (N=negative V=overflow B=break D=decimal I=Interrupt Z=Zero C=Carry)
<syntaxhighlight lang=6502asm>php ;NV-BDIZC (N=negative V=overflow B=break D=decimal I=Interrupt Z=Zero C=Carry)
pla
pla
and #%00010000
and #%00010000
BNE BreakSet</lang>
BNE BreakSet</syntaxhighlight>


This is because the processor flags register doesn't actually contain the true status of the break flag. The only way to read the break flag is to read the flags value that was pushed onto the stack by the hardware itself. Fortunately, this is always at the top of the stack just after an interrupt. Unfortunately, we can't read the flags without clobbering at least one of our registers, something we can't afford to do during an interrupt of any kind. So we'll need to account for the registers we're pushing onto the stack when searching for the flags.
This is because the processor flags register doesn't actually contain the true status of the break flag. The only way to read the break flag is to read the flags value that was pushed onto the stack by the hardware itself. Fortunately, this is always at the top of the stack just after an interrupt. Unfortunately, we can't read the flags without clobbering at least one of our registers, something we can't afford to do during an interrupt of any kind. So we'll need to account for the registers we're pushing onto the stack when searching for the flags.


<lang 6502asm>tempPC_Lo equ $20 ;an arbitrary zero page address set aside for debugging
<syntaxhighlight lang=6502asm>tempPC_Lo equ $20 ;an arbitrary zero page address set aside for debugging
tempPC_Hi equ $21 ;this must be one byte higher than the previous address.
tempPC_Hi equ $21 ;this must be one byte higher than the previous address.


Line 66: Line 66:


org $FFFA
org $FFFA
dw NMI,RESET,IRQ</lang>
dw NMI,RESET,IRQ</syntaxhighlight>


=={{header|68000 Assembly}}==
=={{header|68000 Assembly}}==
Line 72: Line 72:


Precondition example:
Precondition example:
<lang 68000devpac> DIVU D3,D2 ;this will cause a jump to the "divide by zero trap" if D3 = 0.</lang>
<syntaxhighlight lang=68000devpac> DIVU D3,D2 ;this will cause a jump to the "divide by zero trap" if D3 = 0.</syntaxhighlight>


Postcondition examples:
Postcondition examples:
<lang 68000devpac> ADD.L D4,D5
<syntaxhighlight lang=68000devpac> ADD.L D4,D5
TRAPV ;no overflow is expected, so if it occurs call the relevant trap.</lang>
TRAPV ;no overflow is expected, so if it occurs call the relevant trap.</syntaxhighlight>


<lang 68000devpac> LSL.W #8,D2 ;shift D2 left 8 bits.
<syntaxhighlight lang=68000devpac> LSL.W #8,D2 ;shift D2 left 8 bits.
bcc continue ;if carry clear, we're good.
bcc continue ;if carry clear, we're good.
trap 9 ;otherwise call trap 9, which has been defined (in this example only) to handle unexpected carries after a bit shift.
trap 9 ;otherwise call trap 9, which has been defined (in this example only) to handle unexpected carries after a bit shift.


continue: ;the program resumes normally after this point</lang>
continue: ;the program resumes normally after this point</syntaxhighlight>


=={{header|Ada}}==
=={{header|Ada}}==
Ada 2012 introduced aspect specifications to the language. Aspect specifications may be used to specify characteristics about data types, procedures, functions, and tasks. Frequently used aspect specifications for procedures and functions include the ability to specify preconditions and post-conditions. Aspect specifications are written as part of a procedure or function specification such as:
Ada 2012 introduced aspect specifications to the language. Aspect specifications may be used to specify characteristics about data types, procedures, functions, and tasks. Frequently used aspect specifications for procedures and functions include the ability to specify preconditions and post-conditions. Aspect specifications are written as part of a procedure or function specification such as:
<lang Ada>type Nums_Array is array (Integer range <>) of Integer;
<syntaxhighlight lang=Ada>type Nums_Array is array (Integer range <>) of Integer;


procedure Sort(Arr : in out Nums_Array) with
procedure Sort(Arr : in out Nums_Array) with
Pre => Arr'Length > 1,
Pre => Arr'Length > 1,
Post => (for all I in Arr'First .. Arr'Last -1 => Arr(I) <= Arr(I + 1));
Post => (for all I in Arr'First .. Arr'Last -1 => Arr(I) <= Arr(I + 1));
</syntaxhighlight>
</lang>
The precondition above requires the array to be sorted to have more than one data element.
The precondition above requires the array to be sorted to have more than one data element.


Line 97: Line 97:


Post conditions can also reference parameter changes made during the operation of the procedure such as the following procedure specifications for an unbounded queue:
Post conditions can also reference parameter changes made during the operation of the procedure such as the following procedure specifications for an unbounded queue:
<lang Ada> procedure Enqueue (Item : in out Queue; Value : Element_Type) with
<syntaxhighlight lang=Ada> procedure Enqueue (Item : in out Queue; Value : Element_Type) with
Post => Item.Size = Item'Old.Size + 1;
Post => Item.Size = Item'Old.Size + 1;
procedure Dequeue (Item : in out Queue; Value : out Element_Type) with
procedure Dequeue (Item : in out Queue; Value : out Element_Type) with
Pre => not Item.Is_Empty,
Pre => not Item.Is_Empty,
Post => Item.Size = Item'Old.Size - 1;
Post => Item.Size = Item'Old.Size - 1;
</syntaxhighlight>
</lang>
Since this is an unbounded queue there is no size constraint on the Enqueue procedure. The Dequeue procedure can only function properly if the queue is not empty.
Since this is an unbounded queue there is no size constraint on the Enqueue procedure. The Dequeue procedure can only function properly if the queue is not empty.


Line 108: Line 108:


Type invariants can be specified using aspect clauses such as:
Type invariants can be specified using aspect clauses such as:
<lang Ada>subtype Evens is Integer range 0..Integer'Last with
<syntaxhighlight lang=Ada>subtype Evens is Integer range 0..Integer'Last with
Dynamic_Predicate => Evens mod 2 = 0;
Dynamic_Predicate => Evens mod 2 = 0;


Line 118: Line 118:
subtype Alternates is Days with
subtype Alternates is Days with
Static_Predicate => Alternates in Mon | Wed | Fri | Sun;
Static_Predicate => Alternates in Mon | Wed | Fri | Sun;
</syntaxhighlight>
</lang>
The Dynamic_Predicate used for subtype Evens above specifies that each value of the subtype must be an even number.
The Dynamic_Predicate used for subtype Evens above specifies that each value of the subtype must be an even number.


Line 128: Line 128:
{{trans|D}}
{{trans|D}}
Algol W has assertions. Although pre and post conditions are not built in to the language, assertions can be used to simulate them.
Algol W has assertions. Although pre and post conditions are not built in to the language, assertions can be used to simulate them.
<lang algolw>begin
<syntaxhighlight lang=algolw>begin
long real procedure averageOfAbsolutes( integer array values( * )
long real procedure averageOfAbsolutes( integer array values( * )
; integer value valuesLength
; integer value valuesLength
Line 148: Line 148:
write( averageOfAbsolutes( v, 2 ) )
write( averageOfAbsolutes( v, 2 ) )
end
end
end.</lang>
end.</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 156: Line 156:
=={{header|D}}==
=={{header|D}}==
D has exceptions, errors and asserts. In Phobos there is also an enforce(). D has pre-conditions and post conditions, and struct/class invariants. Class method contracts should work correctly in object oriented code with inheritance.
D has exceptions, errors and asserts. In Phobos there is also an enforce(). D has pre-conditions and post conditions, and struct/class invariants. Class method contracts should work correctly in object oriented code with inheritance.
<lang d>import std.stdio, std.algorithm, std.math;
<syntaxhighlight lang=d>import std.stdio, std.algorithm, std.math;


double averageOfAbsolutes(in int[] values) pure nothrow @safe @nogc
double averageOfAbsolutes(in int[] values) pure nothrow @safe @nogc
Line 182: Line 182:
Foo f;
Foo f;
f.inc;
f.inc;
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>2</pre>
<pre>2</pre>
Line 188: Line 188:
=={{header|Eiffel}}==
=={{header|Eiffel}}==
{{trans|D}}
{{trans|D}}
<lang eiffel> acc: INTEGER
<syntaxhighlight lang=eiffel> acc: INTEGER
average_of_absolutes (values: ARRAY[INTEGER]): INTEGER
average_of_absolutes (values: ARRAY[INTEGER]): INTEGER
require
require
Line 198: Line 198:
ensure
ensure
non_neg_result: Result >= 0
non_neg_result: Result >= 0
end</lang>
end</syntaxhighlight>


=={{header|Fortran}}==
=={{header|Fortran}}==
Fortran offers no formal "assert" protocol, but there would be nothing to stop a programmer devising a subroutine such as <lang Fortran> SUBROUTINE AFFIRM(CONDITION,MESSAGE)
Fortran offers no formal "assert" protocol, but there would be nothing to stop a programmer devising a subroutine such as <syntaxhighlight lang=Fortran> SUBROUTINE AFFIRM(CONDITION,MESSAGE)
LOGICAL CONDITION
LOGICAL CONDITION
CHARACTER*(*) MESSAGE
CHARACTER*(*) MESSAGE
Line 207: Line 207:
WRITE (6,*) MESSAGE
WRITE (6,*) MESSAGE
STOP "Oops. Confusion!"
STOP "Oops. Confusion!"
END </lang>
END </syntaxhighlight>
And then scattering through the source file lines such as <lang Fortran> CALL AFFIRM(SSQ.GE.0,"Sum of squares can't be negative.") !Perhaps two passes should be used.</lang>
And then scattering through the source file lines such as <syntaxhighlight lang=Fortran> CALL AFFIRM(SSQ.GE.0,"Sum of squares can't be negative.") !Perhaps two passes should be used.</syntaxhighlight>
And this could be combined with the arrangements described in [[Stack_traces#Fortran]] to provide further interesting information.
And this could be combined with the arrangements described in [[Stack_traces#Fortran]] to provide further interesting information.


As written, the scheme involves an unconditional invocation of a subroutine with parameters. That overhead would be reduced by something like <lang Fortran> IF (SSQ.LT.0) CALL CROAK("Sum of squares can't be negative.") !Perhaps two passes should be used.</lang>
As written, the scheme involves an unconditional invocation of a subroutine with parameters. That overhead would be reduced by something like <syntaxhighlight lang=Fortran> IF (SSQ.LT.0) CALL CROAK("Sum of squares can't be negative.") !Perhaps two passes should be used.</syntaxhighlight>


Some compilers allowed a D in column one to signify that this was a debugging statement, and a compiler option could specify that all such statements were to be treated as comments and not compiled. Probably not a good idea for statements performing checks. The code that is run with intent to produce results should be the same code that you have tested... A variation on this theme involves such debugging output being written to a file, then after modifying and recompiling, the new version's execution proceeds only while it produces the same debugging output. The reference output could be considered a (voluminous) contract, but for this to work a special testing environment is required and is not at all a Fortran standard.
Some compilers allowed a D in column one to signify that this was a debugging statement, and a compiler option could specify that all such statements were to be treated as comments and not compiled. Probably not a good idea for statements performing checks. The code that is run with intent to produce results should be the same code that you have tested... A variation on this theme involves such debugging output being written to a file, then after modifying and recompiling, the new version's execution proceeds only while it produces the same debugging output. The reference output could be considered a (voluminous) contract, but for this to work a special testing environment is required and is not at all a Fortran standard.
Line 218: Line 218:


FreeBASIC provides three assertions. The <code>#assert</code> preprocessor directive will cause compilation to halt with an error message if its argument evaluates to zero:
FreeBASIC provides three assertions. The <code>#assert</code> preprocessor directive will cause compilation to halt with an error message if its argument evaluates to zero:
<lang freebasic>#assert SCREENX >= 320</lang>
<syntaxhighlight lang=freebasic>#assert SCREENX >= 320</syntaxhighlight>


The macro <code>assert</code> will halt at runtime with an error message if its argument evaluates to zero:
The macro <code>assert</code> will halt at runtime with an error message if its argument evaluates to zero:
<lang freebasic>'compile with the -g flag
<syntaxhighlight lang=freebasic>'compile with the -g flag
assert( Pi < 3 )</lang>
assert( Pi < 3 )</syntaxhighlight>


Finally, <code>assertwarn</code> is like <code>assert</code> but only prints an error message and continues running:
Finally, <code>assertwarn</code> is like <code>assert</code> but only prints an error message and continues running:
<lang freebasic>'compile with the -g flag
<syntaxhighlight lang=freebasic>'compile with the -g flag
dim as integer a = 2
dim as integer a = 2
assertwarn( a+a=5 )
assertwarn( a+a=5 )
print "Ha, no."</lang>
print "Ha, no."</syntaxhighlight>


All three show the line number of the failed assertion and the expression that failed, making these nicely self-documenting.
All three show the line number of the failed assertion and the expression that failed, making these nicely self-documenting.
Line 247: Line 247:


If someone disagrees and they ''really'' want to use an "assert" they can simply roll their own:
If someone disagrees and they ''really'' want to use an "assert" they can simply roll their own:
<lang go>func assert(t bool, s string) {
<syntaxhighlight lang=go>func assert(t bool, s string) {
if !t {
if !t {
panic(s)
panic(s)
Line 254: Line 254:
//…
//…
assert(c == 0, "some text here")
assert(c == 0, "some text here")
</syntaxhighlight>
</lang>
(And if the assert function was defined in a file with build constraints and a stub in a file with the opposite constraint then they could be effectively be enabled/disabled at compile time. That's probably a bad idea.)
(And if the assert function was defined in a file with build constraints and a stub in a file with the opposite constraint then they could be effectively be enabled/disabled at compile time. That's probably a bad idea.)


Line 260: Line 260:
J can load scripts expecting any non-assigned noun result to be all 1's.
J can load scripts expecting any non-assigned noun result to be all 1's.
If the file tautology_script.ijs contains
If the file tautology_script.ijs contains
<syntaxhighlight lang=J>
<lang J>
NB. demonstrate properties of arithmetic
NB. demonstrate properties of arithmetic
'A B C' =: 3 ?@$ 0 NB. A B and C are random floating point numbers in range [0, 1).
'A B C' =: 3 ?@$ 0 NB. A B and C are random floating point numbers in range [0, 1).
Line 267: Line 267:
(A * B) -: (B * A) NB. scalar multiplication commutes
(A * B) -: (B * A) NB. scalar multiplication commutes
(A * (B + C)) -: ((A * B) + (A * C)) NB. distributive property
(A * (B + C)) -: ((A * B) + (A * C)) NB. distributive property
</syntaxhighlight>
</lang>
we could load it into a session as 0!:3<'tautology_script.ijs' with result of 1, because the expressions match (-:). Were a sentence to fail the result would be 0, as for example replacing multiplication with matrix product and A B and C with square matrices of same size.
we could load it into a session as 0!:3<'tautology_script.ijs' with result of 1, because the expressions match (-:). Were a sentence to fail the result would be 0, as for example replacing multiplication with matrix product and A B and C with square matrices of same size.


In next example the assertion both tests substitute when the script loads and shows how to use substitute. Infinity (_) replaces the zeros in the y argument, and the x argument is the vector zero infinity.
In next example the assertion both tests substitute when the script loads and shows how to use substitute. Infinity (_) replaces the zeros in the y argument, and the x argument is the vector zero infinity.
<syntaxhighlight lang=J>
<lang J>
substitute =: 4 : '[&.((y~:{.x)&(#!.({:x)))y'
substitute =: 4 : '[&.((y~:{.x)&(#!.({:x)))y'
assert _ 1 1 _ 2 -: 0 _ substitute 0 1 1 0 2
assert _ 1 1 _ 2 -: 0 _ substitute 0 1 1 0 2
</lang>
</syntaxhighlight>




Pre-condition adverbs with example:
Pre-condition adverbs with example:
<syntaxhighlight lang=J>
<lang J>
Positive =: adverb define
Positive =: adverb define
'non-positive' assert *./ , y > 0
'non-positive' assert *./ , y > 0
Line 299: Line 299:
|non-positive: assert
|non-positive: assert
| 'non-positive' assert*./,y>0
| 'non-positive' assert*./,y>0
</syntaxhighlight>
</lang>


As a post-condition, and this is contrived because a better definition of exact_factorial would be !@:x: ,
As a post-condition, and this is contrived because a better definition of exact_factorial would be !@:x: ,
<syntaxhighlight lang=J>
<lang J>
IntegralResult =: adverb define
IntegralResult =: adverb define
RESULT =. u y
RESULT =. u y
Line 324: Line 324:
|use extended precision!: assert
|use extended precision!: assert
| 'use extended precision!' assert(<datatype RESULT)e.;:'extended integer'
| 'use extended precision!' assert(<datatype RESULT)e.;:'extended integer'
</syntaxhighlight>
</lang>


One could assert an invariant in quicksort such that following the split the maximum of the small group is less than the minimum of the large group:
One could assert an invariant in quicksort such that following the split the maximum of the small group is less than the minimum of the large group:
Line 332: Line 332:
The ''-ea'' or ''-enableassertions'' option must be passed to the VM when running the application for this to work.<br>
The ''-ea'' or ''-enableassertions'' option must be passed to the VM when running the application for this to work.<br>
Example taken from [[Perceptron#Java|Perceptron task]].
Example taken from [[Perceptron#Java|Perceptron task]].
<lang java>(...)
<syntaxhighlight lang=java>(...)
int feedForward(double[] inputs) {
int feedForward(double[] inputs) {
assert inputs.length == weights.length : "weights and input length mismatch";
assert inputs.length == weights.length : "weights and input length mismatch";
Line 342: Line 342:
return activate(sum);
return activate(sum);
}
}
(...)</lang>
(...)</syntaxhighlight>


=={{header|Julia}}==
=={{header|Julia}}==
The @assert macro is used for assertions in Julia.
The @assert macro is used for assertions in Julia.
<lang julia>function volumesphere(r)
<syntaxhighlight lang=julia>function volumesphere(r)
@assert(r > 0, "Sphere radius must be positive")
@assert(r > 0, "Sphere radius must be positive")
return π * r^3 * 4.0 / 3.0
return π * r^3 * 4.0 / 3.0
end
end
</syntaxhighlight>
</lang>


=={{header|Kotlin}}==
=={{header|Kotlin}}==
<lang scala>// version 1.1.2
<syntaxhighlight lang=scala>// version 1.1.2
// requires -ea JVM option
// requires -ea JVM option


Line 360: Line 360:
println("The following command line arguments have been passed:")
println("The following command line arguments have been passed:")
for (arg in args) println(arg)
for (arg in args) println(arg)
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 384: Line 384:
Here is an example:
Here is an example:


<lang Nim>import math
<syntaxhighlight lang=Nim>import math


func isqrt(n: int): int =
func isqrt(n: int): int =
assert n >= 0, "argument of “isqrt” cannot be negative"
assert n >= 0, "argument of “isqrt” cannot be negative"
int(sqrt(n.toFloat))</lang>
int(sqrt(n.toFloat))</syntaxhighlight>


If the assertion is not true, the program terminates in error with the exception AssertionDefect:
If the assertion is not true, the program terminates in error with the exception AssertionDefect:
Line 395: Line 395:
Note also that, in this case, rather than using an assertion, we could have simply specified that “n” must be a natural:
Note also that, in this case, rather than using an assertion, we could have simply specified that “n” must be a natural:


<lang nim>import math
<syntaxhighlight lang=nim>import math


func isqrt(n: Natural): int =
func isqrt(n: Natural): int =
int(sqrt(n.toFloat))</lang>
int(sqrt(n.toFloat))</syntaxhighlight>


If the argument is negative, we get the following error:
If the argument is negative, we get the following error:
Line 405: Line 405:
=={{header|Perl}}==
=={{header|Perl}}==
{{trans|Raku}}
{{trans|Raku}}
<lang Perl># 20201201 added Perl programming solution
<syntaxhighlight lang=Perl># 20201201 added Perl programming solution


use strict;
use strict;
Line 431: Line 431:
MessageMultiplier->new(2,'A')->execute;
MessageMultiplier->new(2,'A')->execute;
dies_ok { MessageMultiplier->new(1,'B')->execute };
dies_ok { MessageMultiplier->new(1,'B')->execute };
dies_ok { MessageMultiplier->new(3, '')->execute };</lang>
dies_ok { MessageMultiplier->new(3, '')->execute };</syntaxhighlight>
{{out}}
{{out}}
<pre>1..2
<pre>1..2
Line 440: Line 440:
=={{header|Phix}}==
=={{header|Phix}}==
User defined types can be used to directly implement design by contract, and disabled by "without type_check".
User defined types can be used to directly implement design by contract, and disabled by "without type_check".
<!--<lang Phix>-->
<!--<syntaxhighlight lang=Phix>-->
<span style="color: #008080;">type</span> <span style="color: #000000;">hour</span><span style="color: #0000FF;">(</span><span style="color: #004080;">object</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">type</span> <span style="color: #000000;">hour</span><span style="color: #0000FF;">(</span><span style="color: #004080;">object</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #004080;">integer</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">and</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">>=</span><span style="color: #000000;">0</span> <span style="color: #008080;">and</span> <span style="color: #000000;">x</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">23</span>
<span style="color: #008080;">return</span> <span style="color: #004080;">integer</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">and</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">>=</span><span style="color: #000000;">0</span> <span style="color: #008080;">and</span> <span style="color: #000000;">x</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">23</span>
Line 447: Line 447:
<span style="color: #000000;">h</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span> <span style="color: #000080;font-style:italic;">-- fine</span>
<span style="color: #000000;">h</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span> <span style="color: #000080;font-style:italic;">-- fine</span>
<span style="color: #000000;">h</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">26</span> <span style="color: #000080;font-style:italic;">-- bad (desktop/Phix only)</span>
<span style="color: #000000;">h</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">26</span> <span style="color: #000080;font-style:italic;">-- bad (desktop/Phix only)</span>
<!--</lang>-->
<!--</syntaxhighlight>-->
{{out}}
{{out}}
<pre>
<pre>
Line 456: Line 456:


You can also (since 0.8.2) use standard assert statemnents, eg
You can also (since 0.8.2) use standard assert statemnents, eg
<!--<lang Phix>(phixonline)-->
<!--<syntaxhighlight lang=Phix>(phixonline)-->
<span style="color: #004080;">integer</span> <span style="color: #000000;">fn</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">-1</span> <span style="color: #000080;font-style:italic;">-- (try also 1)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">fn</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">-1</span> <span style="color: #000080;font-style:italic;">-- (try also 1)</span>
<span style="color: #7060A8;">assert</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">!=-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"cannot open config file"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">assert</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">!=-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"cannot open config file"</span><span style="color: #0000FF;">)</span>
<!--</lang>-->
<!--</syntaxhighlight>-->


=={{header|Racket}}==
=={{header|Racket}}==
Line 476: Line 476:
This example is extremely surface-scratching.
This example is extremely surface-scratching.


<lang racket>
<syntaxhighlight lang=racket>
#lang racket
#lang racket
(require racket/contract)
(require racket/contract)
Line 531: Line 531:
;; the bad function doesn't have a chance to generate an invalid reply
;; the bad function doesn't have a chance to generate an invalid reply
(show-contract-failure (average-of-absolutes:bad 42))
(show-contract-failure (average-of-absolutes:bad 42))
(show-contract-failure (average-of-absolutes:bad '())))</lang>
(show-contract-failure (average-of-absolutes:bad '())))</syntaxhighlight>


{{out}}
{{out}}
Line 611: Line 611:


In this snippet, the routine repeat takes one Integer that must be greater than 1, a String and returns a String. (Note that as written, it is incorrect since it actually returns a boolean.)
In this snippet, the routine repeat takes one Integer that must be greater than 1, a String and returns a String. (Note that as written, it is incorrect since it actually returns a boolean.)
<lang perl6>sub repeat ( Int $repeat where * > 1, Str $message, --> Str ) {
<syntaxhighlight lang=perl6>sub repeat ( Int $repeat where * > 1, Str $message, --> Str ) {
say $message x $repeat;
say $message x $repeat;
True # wrong return type
True # wrong return type
Line 631: Line 631:
.resume;
.resume;
}
}
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>AA
<pre>AA
Line 647: Line 647:
This is just a simple method of &nbsp; ''assertion''; &nbsp; more informative messages could be added in the &nbsp; '''assertion''' &nbsp; routine.
This is just a simple method of &nbsp; ''assertion''; &nbsp; more informative messages could be added in the &nbsp; '''assertion''' &nbsp; routine.
<br>A &nbsp; '''return''' &nbsp; statement could've been used instead of an &nbsp; '''exit''' &nbsp; statement to continue processing.
<br>A &nbsp; '''return''' &nbsp; statement could've been used instead of an &nbsp; '''exit''' &nbsp; statement to continue processing.
<lang rexx>/*REXX program demonstrates a method on how to use assertions in design by contract.*/
<syntaxhighlight lang=rexx>/*REXX program demonstrates a method on how to use assertions in design by contract.*/
parse arg top . /*obtain optional argument from the CL.*/
parse arg top . /*obtain optional argument from the CL.*/
if top=='' | top=="," then top= 100 /*Not specified? Then use the default.*/
if top=='' | top=="," then top= 100 /*Not specified? Then use the default.*/
Line 668: Line 668:
say 'ASSERT is exiting.'; exit 13
say 'ASSERT is exiting.'; exit 13
/*──────────────────────────────────────────────────────────────────────────────────────*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
sumABC: procedure; parse arg x,y,z; return x+y+z /*Sum three arguments. Real easy work.*/</lang>
sumABC: procedure; parse arg x,y,z; return x+y+z /*Sum three arguments. Real easy work.*/</syntaxhighlight>
{{out|output|text=&nbsp; when using the default input:}}
{{out|output|text=&nbsp; when using the default input:}}
<pre>
<pre>
Line 696: Line 696:


=={{header|Ruby}}==
=={{header|Ruby}}==
<lang ruby>
<syntaxhighlight lang=ruby>
require 'contracts'
require 'contracts'
include Contracts
include Contracts
Line 706: Line 706:


puts double("oops")
puts double("oops")
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 719: Line 719:
=={{header|Scala}}==
=={{header|Scala}}==
Scala provides runtime assertions like Java: they are designed to be used by static analysis tools however the default compiler doesn’t perform such analyses by default. The Scala assertions (<tt>assume</tt>, <tt>require</tt>, <tt>assert</tt>, <tt>ensuring</tt>) are [http://www.scala-lang.org/api/current/index.html#scala.Predef$ Predef library] methods that are enabled by default and can be disabled using the <tt>-Xdisable-assertions</tt> runtime flag, unlike Java where assertions are disabled by default and enabled with a runtime flag. It is considered poor form to rely on assertions to validate arguments, because they can be disabled. An appropriate informative runtime exception (e.g. NullPointerException or IllegalArgumentException) should be thrown instead.
Scala provides runtime assertions like Java: they are designed to be used by static analysis tools however the default compiler doesn’t perform such analyses by default. The Scala assertions (<tt>assume</tt>, <tt>require</tt>, <tt>assert</tt>, <tt>ensuring</tt>) are [http://www.scala-lang.org/api/current/index.html#scala.Predef$ Predef library] methods that are enabled by default and can be disabled using the <tt>-Xdisable-assertions</tt> runtime flag, unlike Java where assertions are disabled by default and enabled with a runtime flag. It is considered poor form to rely on assertions to validate arguments, because they can be disabled. An appropriate informative runtime exception (e.g. NullPointerException or IllegalArgumentException) should be thrown instead.
<lang Scala>object AssertionsInDesignByContract extends App {
<syntaxhighlight lang=Scala>object AssertionsInDesignByContract extends App {
/**
/**
* @param ints a non-empty array of integers
* @param ints a non-empty array of integers
Line 743: Line 743:
println(averageOfMagnitudes(Array(Integer.MAX_VALUE, Integer.MAX_VALUE))) // java.lang.AssertionError: assertion failed: magnitude must be within range
println(averageOfMagnitudes(Array(Integer.MAX_VALUE, Integer.MAX_VALUE))) // java.lang.AssertionError: assertion failed: magnitude must be within range
println(averageOfMagnitudes(Array(Integer.MAX_VALUE, 1))) // java.lang.AssertionError: assertion failed: result must be non-negative (possible overflow)
println(averageOfMagnitudes(Array(Integer.MAX_VALUE, 1))) // java.lang.AssertionError: assertion failed: result must be non-negative (possible overflow)
}</lang>
}</syntaxhighlight>


=={{header|Tcl}}==
=={{header|Tcl}}==
<lang tcl># Custom assertions; names stolen from Eiffel keywords
<syntaxhighlight lang=tcl># Custom assertions; names stolen from Eiffel keywords
proc require {expression message args} {
proc require {expression message args} {
if {![uplevel 1 [list expr $expression]]} {
if {![uplevel 1 [list expr $expression]]} {
Line 772: Line 772:


return $sock
return $sock
}</lang>
}</syntaxhighlight>
This can be usefully mixed with Tcl 8.6's <code>try … finally …</code> built-in command.
This can be usefully mixed with Tcl 8.6's <code>try … finally …</code> built-in command.


Line 787: Line 787:
{{libheader|Wren-assert}}
{{libheader|Wren-assert}}
Wren doesn't support assertions natively though they (and design by contract) can be simulated using a library.
Wren doesn't support assertions natively though they (and design by contract) can be simulated using a library.
<lang ecmascript>import "/assert" for Assert
<syntaxhighlight lang=ecmascript>import "/assert" for Assert
import "/math" for Nums
import "/math" for Nums


Line 827: Line 827:
var f = Foo.new(-1)
var f = Foo.new(-1)
f.inc
f.inc
System.print(f.x)</lang>
System.print(f.x)</syntaxhighlight>


{{out}}
{{out}}
Line 849: Line 849:
=={{header|Z80 Assembly}}==
=={{header|Z80 Assembly}}==
There are no built-in assertions, error handlers, etc. at the hardware level. The closest you can get is a function conditionally returning early. For example, this function for multiplication checks if the second factor equals zero or 1 before attempting to multiply.
There are no built-in assertions, error handlers, etc. at the hardware level. The closest you can get is a function conditionally returning early. For example, this function for multiplication checks if the second factor equals zero or 1 before attempting to multiply.
<lang z80>SmallMultiply:
<syntaxhighlight lang=z80>SmallMultiply:
;returns A = C * A
;returns A = C * A
or a ;compares A to zero
or a ;compares A to zero
Line 865: Line 865:
C_Times_One:
C_Times_One:
ld a,c
ld a,c
ret ;returns A = C</lang>
ret ;returns A = C</syntaxhighlight>


=={{header|zkl}}==
=={{header|zkl}}==
zkl has exceptions. The _assert_ keyword just wraps the AssertionError exception. _assert_ takes an expression and optional message.
zkl has exceptions. The _assert_ keyword just wraps the AssertionError exception. _assert_ takes an expression and optional message.
There are no pre/post conditionals.
There are no pre/post conditionals.
<lang zkl>fcn f(a){
<syntaxhighlight lang=zkl>fcn f(a){
_assert_((z:=g())==5,"I wanted 5, got "+z)
_assert_((z:=g())==5,"I wanted 5, got "+z)
}</lang>
}</syntaxhighlight>
Running the code throws an exception with file and line number:
Running the code throws an exception with file and line number:
{{out}}
{{out}}