Next: , Previous: Installing, Up: Top   [Contents]


2 Common programming errors

  1. What does the error message “undefined symbol ‘'.'/2’” mean?

    You need to explicitly import the ‘list’ module

    :- import_module list.
    

    if your code uses lists. Similarly, if your code uses arithmetic operations, you will need to import the ‘int’ and possibly ‘float’ modules.


  2. Why doesn’t ‘X <= 3’ work?

    In Mercury, less-than-or-equal-to is written as ‘=<’ not as ‘<=’, which is used for reverse implication.


  3. I defined a type like this: ‘:- type number ---> int ; float.’ Why doesn’t this work?

    You tried to define a type that is an undiscriminated union of two types, which is not allowed by the Mercury type system. The declaration above defines an enumerated type with two constants, “int” and “float”. This is not what you want, but it is legal Mercury, which is why you don’t get an error message on the type declaration itself.


  4. I get a “scope error” in an if-then-else. I checked and both branches bind the same variables. What is the error?

    This error generally happens if you attempt bind non-local variables in the condition of the if-then-else. For example, the following code attempts to bind ‘Value’ in the call to ‘map.search’, but ‘Value’ occurs outside of the if-then-else — in particular, it occurs in the head of the clause.

    :- pred map.search(map(K, V), K, V).
    :- mode map.search(in, in, out) is semidet.
    
    :- pred lookup(map(string, int), string, int).
    :- mode lookup(in, in, out) is det.
    
    lookup(Map, Key, Value) :-
            (if map.search(Map, Key, Value) then
                    true
            else
                    Value = -1
            ).
    

    Binding non-local variables in the condition of an if-then-else is forbidden since it would be unsound; it would lead to inconsistent results. For example, ‘(X = 1 -> Y = 1 ; Y = 2), X = 2’ would fail, but ‘X = 2, (X = 1 -> Y = 1 ; Y = 2)’ would succeed — breaking one of the fundamental laws of logic, ‘(P, Q) <=> (Q, P)’.

    Mode analysis therefore rejects such programs. (In certain rare circumstances, the compiler may report this as a “mode error” rather than a “scope error”.) The way to fix such errors is to avoid binding non-local variables in the condition, and instead bind them in the then part of the if-then-else. So in the above example, you should introduce a new local variable, which we will call ‘Value1’:

    lookup(Map, Key, Value) :-
            ( map.search(Map, Key, Value1) ->
                    Value = Value1
            ;
                    Value = -1
            ).
    
  5. “I keep getting a link error ‘undefined symbol init_gc’. Why?”

    If you are using ‘mmake’ to recompile your program, and you are overriding the default grade (e.g. by setting ‘GRADE=asm_fast’ in your ‘Mmake’ file), you must make sure that you do ‘mmake clean’ every time you change grades.


Next: , Previous: Installing, Up: Top   [Contents]