Errors

Ambiguous identifier

Incorrect

Correct

import module { a = 1 }
import module { a = 2 }

print a
import module { a = 1 } as x
import module { a = 2 } as y

print x.a

Ambiguous identifier ‘a’ could refer to anonymous module import on line 1 or anonymous module import on line 2. Please remove one import or disambiguate using qualified names.

Automatic error propagation

Incorrect

Correct

a = error "urk"
b = a + 2
main = print b
a = error "urk"
b = case a of
  (e : Exception) -> e
  a -> a + 2
main = print b

Exception “urk” may be thrown by ‘a’ and automatically propagated out of ‘b’. Consider adding explicit exception handling or marking with the function ‘rethrowing’.

Bad indentation

Incorrect

Correct

f =
  a = 1
	b = 2
  return (a+b)

print f
f =
  a = 1
  b = 2
  return (a+b)

print f

Mismatched indentation: line 2 uses 2 spaces, but line 3 uses 1 tab. Use consistent indentation.

Shadowing in a block

Incorrect

Correct

main =
  a = 1
  a = 2
  print a
main =
  a = 2
  print a

Second declaration of ‘a’ shadows earlier declaration. I suggest renaming or deleting one of the declarations.

Confusuable Unicode

Incorrect

Correct

µ = 1/1000000
μ = "greek mu"
print [µ, μ]
µ1 = 1/1000000
μ2 = "greek mu"
print [µ1, μ2]

Identifiers ‘µ’ (MICRO SIGN) and ‘μ’ (GREEK SMALL LETTER MU) look very similar in common fonts. Change them to be more visually distinct.

Default arguments

Incorrect

Correct

a {x=1,y=2} = x + y

main = print a
a {x=1,y=2} = x + y

main = print (a {x=1,y=2})

Function ‘a’ is called using default values of parameters ‘x’, ‘y’. Please call the function using explicit values ‘a {x=1,y=2}’.

Deprecated default arguments

Incorrect

Correct

a {x = 2 !deprecated} = x * 3
main =
  print a
a {x = 2 !deprecated} = x * 3
main =
  print (a {x=2})

The default value of argument ‘x’ of function ‘a’ has been deprecated and may be removed in a future release. Please add the explicit value ‘{x = 2}’.

Equal priority clauses

Incorrect

Correct

clause c1
f 1 y = 1

clause c2
f x 2 = 2

prioConstrain c1 = c2
clause c1
f 1 y = 1

clause c2
f x 2 = 2

clause c3
f 1 2 = 3

prioConstrain c1 = c2 = c3

Clauses ‘c1’ and ‘c2’ have equal declared priority, but neither is more specific than the other. Furthermore they conflict for the expression ‘f 1 2’. Set one to have higher priority or fix the conflict.

Failed assert

Incorrect

Correct

a = 0
print "test"
assert (a != 0)
a = 1
print "test"
assert (a != 0)

Assertion ‘a != 0’ failed. ‘a’ received its value ‘0’ at line 1. You may change the assertion or ensure ‘a’ receives a different value.

Implicit argument not passed

Incorrect

Correct

a k = 1
b k = k + a

print (b {k:2})
a k = 1
b k = k + a { k=k }

print (b {k:2})

Argument ‘k’ of function ‘b’ was not passed implicitly to ‘a’, leading to it being undefined. I suggest passing it explicitly.

Inapplicable to type

Incorrect

Correct

a = i16 1
foo (n : i32) = n * 2
main =
  print (foo a)
a = i32 1
foo (n : i32) = n * 2
main =
  print (foo a)

Function foo does not have any rules for value ‘i16 1’. The most similar rule is ‘foo (n : i32)’. Consider modifying the type of ‘a’ or adding another reduction rule.

Invalid UTF8

Incorrect

Correct

UTF-8 decoder capability and stress test
----------------------------------------

Markus Kuhn <https://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt> - 2015-08-28 - CC BY 4.0

3  Malformed sequences                                                        |
                                                                              |
3.1  Unexpected continuation bytes                                            |
                                                                              |
Each unexpected continuation byte should be separately signalled as a         |
malformed sequence of its own.                                                |
                                                                              |
3.1.1  First continuation byte 0x80: "�"                                      |
3.1.2  Last  continuation byte 0xbf: "�"                                      |
                                                                              |
3.1.3  2 continuation bytes: "��"                                             |
3.1.4  3 continuation bytes: "���"                                            |
3.1.5  4 continuation bytes: "����"                                           |
3.1.6  5 continuation bytes: "�����"                                          |
3.1.7  6 continuation bytes: "������"                                         |
3.1.8  7 continuation bytes: "�������"                                        |
                                                                              |
3.1.9  Sequence of all 64 possible continuation bytes (0x80-0xbf):            |
                                                                              |
   "����������������                                                          |
    ����������������                                                          |
    ����������������                                                          |
    ����������������"                                                         |
                                                                              |
3.2  Lonely start characters                                                  |
                                                                              |
3.2.1  All 32 first bytes of 2-byte sequences (0xc0-0xdf),                    |
       each followed by a space character:                                    |
                                                                              |
   "� � � � � � � � � � � � � � � �                                           |
    � � � � � � � � � � � � � � � � "                                         |
                                                                              |
3.2.2  All 16 first bytes of 3-byte sequences (0xe0-0xef),                    |
       each followed by a space character:                                    |
                                                                              |
   "� � � � � � � � � � � � � � � � "                                         |
                                                                              |
3.2.3  All 8 first bytes of 4-byte sequences (0xf0-0xf7),                     |
       each followed by a space character:                                    |
                                                                              |
   "� � � � � � � � "                                                         |
                                                                              |
3.2.4  All 4 first bytes of 5-byte sequences (0xf8-0xfb),                     |
       each followed by a space character:                                    |
                                                                              |
   "� � � � "                                                                 |
                                                                              |
3.2.5  All 2 first bytes of 6-byte sequences (0xfc-0xfd),                     |
       each followed by a space character:                                    |
                                                                              |
   "� � "                                                                     |
                                                                              |
3.3  Sequences with last continuation byte missing                            |
                                                                              |
All bytes of an incomplete sequence should be signalled as a single           |
malformed sequence, i.e., you should see only a single replacement            |
character in each of the next 10 tests. (Characters as in section 2)          |
                                                                              |
3.3.1  2-byte sequence with last byte missing (U+0000):     "�"               |
3.3.2  3-byte sequence with last byte missing (U+0000):     "��"               |
3.3.3  4-byte sequence with last byte missing (U+0000):     "���"               |
3.3.4  5-byte sequence with last byte missing (U+0000):     "����"               |
3.3.5  6-byte sequence with last byte missing (U+0000):     "�����"               |
3.3.6  2-byte sequence with last byte missing (U-000007FF): "�"               |
3.3.7  3-byte sequence with last byte missing (U-0000FFFF): "�"               |
3.3.8  4-byte sequence with last byte missing (U-001FFFFF): "���"               |
3.3.9  5-byte sequence with last byte missing (U-03FFFFFF): "����"               |
3.3.10 6-byte sequence with last byte missing (U-7FFFFFFF): "�����"               |
                                                                              |
3.4  Concatenation of incomplete sequences                                    |
                                                                              |
All the 10 sequences of 3.3 concatenated, you should see 10 malformed         |
sequences being signalled:                                                    |
                                                                              |
   "�����������������������������"                                                               |
                                                                              |
3.5  Impossible bytes                                                         |
                                                                              |
The following two bytes cannot appear in a correct UTF-8 string               |
                                                                              |
3.5.1  fe = "�"                                                               |
3.5.2  ff = "�"                                                               |
3.5.3  fe fe ff ff = "����"                                                   |
                                                                              |
4.1  Examples of an overlong ASCII character                                  |
                                                                              |
With a safe UTF-8 decoder, all of the following five overlong                 |
representations of the ASCII character slash ("/") should be rejected         |
like a malformed UTF-8 sequence, for instance by substituting it with         |
a replacement character. If you see a slash below, you do not have a          |
safe UTF-8 decoder!                                                           |
                                                                              |
4.1.1 U+002F = c0 af             = "��"                                        |
4.1.2 U+002F = e0 80 af          = "���"                                        |
4.1.3 U+002F = f0 80 80 af       = "����"                                        |
4.1.4 U+002F = f8 80 80 80 af    = "�����"                                        |
4.1.5 U+002F = fc 80 80 80 80 af = "������"                                        |
                                                                              |
4.2  Maximum overlong sequences                                               |
                                                                              |
Below you see the highest Unicode value that is still resulting in an         |
overlong sequence if represented with the given number of bytes. This         |
is a boundary test for safe UTF-8 decoders. All five characters should        |
be rejected like malformed UTF-8 sequences.                                   |
                                                                              |
4.2.1  U-0000007F = c1 bf             = "��"                                   |
4.2.2  U-000007FF = e0 9f bf          = "���"                                   |
4.2.3  U-0000FFFF = f0 8f bf bf       = "����"                                   |
4.2.4  U-001FFFFF = f8 87 bf bf bf    = "�����"                                   |
4.2.5  U-03FFFFFF = fc 83 bf bf bf bf = "������"                                   |
                                                                              |
4.3  Overlong representation of the NUL character                             |
                                                                              |
The following five sequences should also be rejected like malformed           |
UTF-8 sequences and should not be treated like the ASCII NUL                  |
character.                                                                    |
                                                                              |
4.3.1  U+0000 = c0 80             = "��"                                       |
4.3.2  U+0000 = e0 80 80          = "���"                                       |
4.3.3  U+0000 = f0 80 80 80       = "����"                                       |
4.3.4  U+0000 = f8 80 80 80 80    = "�����"                                       |
4.3.5  U+0000 = fc 80 80 80 80 80 = "������"                                       |
                                                                              |
5  Illegal code positions                                                     |
                                                                              |
The following UTF-8 sequences should be rejected like malformed               |
sequences, because they never represent valid ISO 10646 characters and        |
a UTF-8 decoder that accepts them might introduce security problems           |
comparable to overlong UTF-8 sequences.                                       |
                                                                              |
5.1 Single UTF-16 surrogates                                                  |
                                                                              |
5.1.1  U+D800 = ed a0 80 = "���"                                                |
5.1.2  U+DB7F = ed ad bf = "���"                                                |
5.1.3  U+DB80 = ed ae 80 = "���"                                                |
5.1.4  U+DBFF = ed af bf = "���"                                                |
5.1.5  U+DC00 = ed b0 80 = "���"                                                |
5.1.6  U+DF80 = ed be 80 = "���"                                                |
5.1.7  U+DFFF = ed bf bf = "���"                                                |
                                                                              |
5.2 Paired UTF-16 surrogates                                                  |
                                                                              |
5.2.1  U+D800 U+DC00 = ed a0 80 ed b0 80 = "������"                               |
5.2.2  U+D800 U+DFFF = ed a0 80 ed bf bf = "������"                               |
5.2.3  U+DB7F U+DC00 = ed ad bf ed b0 80 = "������"                               |
5.2.4  U+DB7F U+DFFF = ed ad bf ed bf bf = "������"                               |
5.2.5  U+DB80 U+DC00 = ed ae 80 ed b0 80 = "������"                               |
5.2.6  U+DB80 U+DFFF = ed ae 80 ed bf bf = "������"                               |
5.2.7  U+DBFF U+DC00 = ed af bf ed b0 80 = "������"                               |
5.2.8  U+DBFF U+DFFF = ed af bf ed bf bf = "������"                               |
                                                                              |
UTF-8 decoder capability and stress test
----------------------------------------

Markus Kuhn <https://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt> - 2015-08-28 - CC BY 4.0

3  Malformed sequences                                                        |
                                                                              |
3.1  Unexpected continuation bytes                                            |
                                                                              |
Each unexpected continuation byte should be separately signalled as a         |
malformed sequence of its own.                                                |
                                                                              |
3.1.1  First continuation byte 0x80: "�"                                      |
3.1.2  Last  continuation byte 0xbf: "�"                                      |
                                                                              |
3.1.3  2 continuation bytes: "��"                                             |
3.1.4  3 continuation bytes: "���"                                            |
3.1.5  4 continuation bytes: "����"                                           |
3.1.6  5 continuation bytes: "�����"                                          |
3.1.7  6 continuation bytes: "������"                                         |
3.1.8  7 continuation bytes: "�������"                                        |
                                                                              |
3.1.9  Sequence of all 64 possible continuation bytes (0x80-0xbf):            |
                                                                              |
   "����������������                                                          |
    ����������������                                                          |
    ����������������                                                          |
    ����������������"                                                         |
                                                                              |
3.2  Lonely start characters                                                  |
                                                                              |
3.2.1  All 32 first bytes of 2-byte sequences (0xc0-0xdf),                    |
       each followed by a space character:                                    |
                                                                              |
   "� � � � � � � � � � � � � � � �                                           |
    � � � � � � � � � � � � � � � � "                                         |
                                                                              |
3.2.2  All 16 first bytes of 3-byte sequences (0xe0-0xef),                    |
       each followed by a space character:                                    |
                                                                              |
   "� � � � � � � � � � � � � � � � "                                         |
                                                                              |
3.2.3  All 8 first bytes of 4-byte sequences (0xf0-0xf7),                     |
       each followed by a space character:                                    |
                                                                              |
   "� � � � � � � � "                                                         |
                                                                              |
3.2.4  All 4 first bytes of 5-byte sequences (0xf8-0xfb),                     |
       each followed by a space character:                                    |
                                                                              |
   "� � � � "                                                                 |
                                                                              |
3.2.5  All 2 first bytes of 6-byte sequences (0xfc-0xfd),                     |
       each followed by a space character:                                    |
                                                                              |
   "� � "                                                                     |
                                                                              |
3.3  Sequences with last continuation byte missing                            |
                                                                              |
All bytes of an incomplete sequence should be signalled as a single           |
malformed sequence, i.e., you should see only a single replacement            |
character in each of the next 10 tests. (Characters as in section 2)          |
                                                                              |
3.3.1  2-byte sequence with last byte missing (U+0000):     "�"               |
3.3.2  3-byte sequence with last byte missing (U+0000):     "��"               |
3.3.3  4-byte sequence with last byte missing (U+0000):     "���"               |
3.3.4  5-byte sequence with last byte missing (U+0000):     "����"               |
3.3.5  6-byte sequence with last byte missing (U+0000):     "�����"               |
3.3.6  2-byte sequence with last byte missing (U-000007FF): "�"               |
3.3.7  3-byte sequence with last byte missing (U-0000FFFF): "�"               |
3.3.8  4-byte sequence with last byte missing (U-001FFFFF): "���"               |
3.3.9  5-byte sequence with last byte missing (U-03FFFFFF): "����"               |
3.3.10 6-byte sequence with last byte missing (U-7FFFFFFF): "�����"               |
                                                                              |
3.4  Concatenation of incomplete sequences                                    |
                                                                              |
All the 10 sequences of 3.3 concatenated, you should see 10 malformed         |
sequences being signalled:                                                    |
                                                                              |
   "�������������������"                                                               |
                                                                              |
3.5  Impossible bytes                                                         |
                                                                              |
The following two bytes cannot appear in a correct UTF-8 string               |
                                                                              |
3.5.1  fe = "�"                                                               |
3.5.2  ff = "�"                                                               |
3.5.3  fe fe ff ff = "����"                                                   |
                                                                              |
4.1  Examples of an overlong ASCII character                                  |
                                                                              |
With a safe UTF-8 decoder, all of the following five overlong                 |
representations of the ASCII character slash ("/") should be rejected         |
like a malformed UTF-8 sequence, for instance by substituting it with         |
a replacement character. If you see a slash below, you do not have a          |
safe UTF-8 decoder!                                                           |
                                                                              |
4.1.1 U+002F = c0 af             = "��"                                        |
4.1.2 U+002F = e0 80 af          = "���"                                        |
4.1.3 U+002F = f0 80 80 af       = "����"                                        |
4.1.4 U+002F = f8 80 80 80 af    = "�����"                                        |
4.1.5 U+002F = fc 80 80 80 80 af = "������"                                        |
                                                                              |
4.2  Maximum overlong sequences                                               |
                                                                              |
Below you see the highest Unicode value that is still resulting in an         |
overlong sequence if represented with the given number of bytes. This         |
is a boundary test for safe UTF-8 decoders. All five characters should        |
be rejected like malformed UTF-8 sequences.                                   |
                                                                              |
4.2.1  U-0000007F = c1 bf             = "��"                                   |
4.2.2  U-000007FF = e0 9f bf          = "���"                                   |
4.2.3  U-0000FFFF = f0 8f bf bf       = "����"                                   |
4.2.4  U-001FFFFF = f8 87 bf bf bf    = "�����"                                   |
4.2.5  U-03FFFFFF = fc 83 bf bf bf bf = "������"                                   |
                                                                              |
4.3  Overlong representation of the NUL character                             |
                                                                              |
The following five sequences should also be rejected like malformed           |
UTF-8 sequences and should not be treated like the ASCII NUL                  |
character.                                                                    |
                                                                              |
4.3.1  U+0000 = c0 80             = "��"                                       |
4.3.2  U+0000 = e0 80 80          = "���"                                       |
4.3.3  U+0000 = f0 80 80 80       = "����"                                       |
4.3.4  U+0000 = f8 80 80 80 80    = "�����"                                       |
4.3.5  U+0000 = fc 80 80 80 80 80 = "������"                                       |
                                                                              |
5  Illegal code positions                                                     |
                                                                              |
The following UTF-8 sequences should be rejected like malformed               |
sequences, because they never represent valid ISO 10646 characters and        |
a UTF-8 decoder that accepts them might introduce security problems           |
comparable to overlong UTF-8 sequences.                                       |
                                                                              |
5.1 Single UTF-16 surrogates                                                  |
                                                                              |
5.1.1  U+D800 = ed a0 80 = "���"                                                |
5.1.2  U+DB7F = ed ad bf = "���"                                                |
5.1.3  U+DB80 = ed ae 80 = "���"                                                |
5.1.4  U+DBFF = ed af bf = "���"                                                |
5.1.5  U+DC00 = ed b0 80 = "���"                                                |
5.1.6  U+DF80 = ed be 80 = "���"                                                |
5.1.7  U+DFFF = ed bf bf = "���"                                                |
                                                                              |
5.2 Paired UTF-16 surrogates                                                  |
                                                                              |
5.2.1  U+D800 U+DC00 = ed a0 80 ed b0 80 = "������"                               |
5.2.2  U+D800 U+DFFF = ed a0 80 ed bf bf = "������"                               |
5.2.3  U+DB7F U+DC00 = ed ad bf ed b0 80 = "������"                               |
5.2.4  U+DB7F U+DFFF = ed ad bf ed bf bf = "������"                               |
5.2.5  U+DB80 U+DC00 = ed ae 80 ed b0 80 = "������"                               |
5.2.6  U+DB80 U+DFFF = ed ae 80 ed bf bf = "������"                               |
5.2.7  U+DBFF U+DC00 = ed af bf ed b0 80 = "������"                               |
5.2.8  U+DBFF U+DFFF = ed af bf ed bf bf = "������"                               |
                                                                              |

Invalid UTF-8 byte sequence replaced.

Map on non-collection

Incorrect

Correct

print (map (+1) 1)
print (map (+1) [1])

Value ‘1’ is not iterable, so ‘map’ is not defined. Try wrapping the value in a list.

Meaningless term

Incorrect

Correct

foo x = foo (x-1)

print (foo 10)
foo 0 = 0
foo x = foo (x-1)

print (foo 10)

Term ‘foo 10’ is meaningless (perpetually reduces). Maybe you forgot a base case?

Missing override

Incorrect

Correct

module1 = module {
  foo (x : i32) = 1
}


module2 = module {
  import module1
  foo (x : i16) = 2
}

import module1, module2

f = force foo
print (map foo [1,2])
module1 = module {
  foo (x : i32) = 1
}


module2 = module {
  import module1
  override foo
  foo (x : i16) = 2
}

import module1, module2

f = force foo
print (map foo [1,2])

Identifier ‘foo’ could refer to ‘module1.foo’ or ‘module2.foo’ and is ambiguous. Specify the module or use ‘override’ to combine the identifiers.

Shadowing nested block

Incorrect

Correct

f = f 4 where
  f 0 = 0
  f x = f (x-1)
assert (f == 0)
f = g 4 where
  g 0 = 0
  g x = g (x-1)
assert (f == 0)

Function declaration ‘f’ on lines 2-3 shadows variable declaration on line 1. I suggest renaming it.

No fixed point

Incorrect

Correct

a | a != b = b

print a
a = b

print a

Rule ‘a | a != b’ contradicts itself and has been ignored. Either simplify the condition or remove the rule.

Nondeterministic use of concurrency

Incorrect

Correct

A = mut 0
t1 = fork { A := 1 }
t2 = fork { A := 2 }
join (t1, t2)
print A
A = mut 0
t1 = fork { A := 1 }
t2 = fork { join t1; A := 2 }
join (t1, t2)
print A

Variable ‘A’ may have multiple values due to concurrent execution. Insert synchronization operations or otherwise ensure that the program is deterministic.

Nondeterministic use of exceptions

Incorrect

Correct

e = throw b + throw c
print (try e)
e =
  b' = force (throw b)
  c' = force (throw c)
  return (b' + c')
print (try e)

Multiple exceptions may be caught in expression ‘try e’. Use ‘force’ to fix the evaluation order.

Top-level non-deteterministic dispatch

Incorrect

Correct

a = b
a = c
print a
a = b
a = c
print (allValuesOf a)

Unresolved nondeterminism at top-level: ‘a’ may evaluate to ‘b’ or ‘c’. Remove the nondeterminism by modifying reduction rules or using a meta-evaluation function such as ‘allValuesOf’.

Applying a non-function

Incorrect

Correct

foo a b = print (a + b)
main = "x" 2
foo a b = print (a + b)
main = foo "x" 2

“x” is not a function. Maybe you forgot a symbol?

Non-NFC

Incorrect

Correct

print "à"
print "à"

Text “à” is not in Unicode Normal Form C. Automatically normalizing.

Non-syntactic use of variadic arguments

Incorrect

Correct

c = sum $arguments

print ((c 1 2) 3)
  # error: 3 3 is not reducible

a = c 1
b = a 2

print b
  # error: 1 2 is not reducible
c = sum $arguments

print (c 1 2 3)

a = \x -> c 1 x
b = a 2

print b

Variadic function ‘c’ was applied but did not return a function, so expression cannot be applied to argument ‘3’. I suggest making ‘3’ a syntactic argument of ‘c’.

Function ‘a’ applied variadic function ‘c’ but did not return a function, so expression cannot be applied to argument ‘2’ in function ‘b’. I suggest adding a parameter to ‘a’.

Too many arguments

Incorrect

Correct

foo x y = x + y
print (foo 1 2 3)
foo x y = x + y
print (foo 1 2)

‘foo’ requires 2 arguments, but has been given 3, and its result is not a function. Try deleting the extra arguments.

Typos in variable name

Incorrect

Correct

test = 1
exmple = 2

main =
  print tst
  print example
test = 1
example = 2

main =
  print test
  print example

Unbound identifier ‘tst’. Did you mean ‘test’?

Unbound identifier ‘example’. Did you mean ‘exmple’?

Unhandled exception

Incorrect

Correct

main =
  print "1"
  throw Error
  print "2"
main =
  print "1"
  print . try $ throw Error
  print "2"

Unhandled exception ‘Error’. Add a try or catch handler.

Unreachable case

Incorrect

Correct

foo 1 = "hello"
foo 2 = "world"

print (foo 1)
foo 1 = "hello"

print (foo 1)

Case ‘foo 2’ is dead code (unreachable). Either remove it or add it to the control flow.

Unreducible expression

Incorrect

Correct

foo 1 = 1

bar (n : Integer) = print "hi"

main =
  bar (foo 2)
foo 1 = 1
foo 2 = 2

bar (n : Integer) = print n

main =
  bar (foo 2)

Expression ‘foo 2’ does not reduce, and there are no matching rules for this expression.

Consider adding a reduction rule.

Unused argument

Incorrect

Correct

k a b = a
k a _ = a

Argument ‘b’ in function declaration ‘k’ is unused. Replace it with a wildcard pattern (‘_’).

Unused import

Incorrect

Correct

import module

print "done"
print "done"

Module import ‘module’ is unused. Remove it.

Unused result

Incorrect

Correct

f = { return 1 }

main =
  f
  print "done"
f = { return 1 }

main =
  void f
  print "done"

Unused result. Try using ‘void’.

Unused definition

Incorrect

Correct

main =
  a = 1
  b = 2
  print a
main =
  a = 1
  print a

Unused variable ‘b’. Try removing it.