errors.xml 7.23 KB
Newer Older
1
2
3
<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
<page name="tutorial_errors">

4
5
<title>Error messages and Warnings</title>
<banner>Error messages and Warnings</banner>
6
7
8

<left>
<boxes-toc/>
9
10
<p>
You can cut and paste the code on this page and 
11
test it on the <a href="http://reglisse.ens.fr/cgi-bin/cduce">online interpreter</a>.
12
</p>
13
14
</left>

15
16


17
18
<box title="Key concepts" link="p1">

19
20
21

<p>
CDuce, statically detects a large class of error and tries to help their
22
debugging by providing precise error messages and, in case of type errors, by
23
24
25
showing a description (we call it a "sample") of specific values that would make
the computation fail.
</p>
26
27
28
29
30
31
32
33
34
35
36
37
38
<p>
CDuce signals the classic syntax errors as well as those for instance of unbound variables. It also checks that pattern matching is exhaustive
  <footnote>
    It checks it in functions, <code>match</code>, and <code>map</code> expressions, but
    not for <code>transform</code> and <code>xtransform</code> for which a default branch
    returning the empty sequence is always defined
  </footnote>.
For instance if we declare the type <code>Person</code> defined in Section "<local href="tutorial_overloading"/>" and  try the following definition:
</p>
<sample><![CDATA[
fun name (Person -> String) 
     | <person gender = {{"F"}}>[ n ;_] -> n 
]]></sample>
39
<p> then we obtain the following message error (frames of the same form as the following denote text taken verbatim from the on line demo, no color or formatting added):</p>
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<sessionsample><![CDATA[
Error at chars 228-298:
{{%%fun name (Person -> String) 
     | <person gender = "F">[ n ;_] -> n%%}} 
This pattern matching is not exhaustive
Residual type:
<person gender = [ 'M' ]>[ Name Children ]
Sample:
<person {| gender = [ 'M' ] |}>[ <name {| |}>[  ] <children {| |}>[  ] ]
]]></sessionsample>
<p>
This error message tells us three things: (1) that pattern matching is not
defined for all the possible input types (as we forgot the case when the
attribute is <code>"M"</code>); (2) it gives us the exact type of the values of
the type we have forgotten in our matching (in this case this is exactly
<code>MPerson</code>); (3) it shows us a "sample" of the residual type, that is
a simplified representation of a value that would make the expression fail (in
this case it shows us the value <code>&lt;person gender="M">[ &lt;name>[ ]
&lt;children>[ ] ]</code>).
</p>
60

61
<note>Samples are  simplified representations of values in the sense that they show 
62
only that part of the value that is relevant for the error and may omit other parts
63
that are needed to obtain an effective value.
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
</note>

<section title="Warnings">
<p>
CDuce use warnings to signal possible subtler errors. So for instance it issues a warning whenever a capture variable of a pattern is not used in the subsequent expression. This is very useful for instance to detect misprinted types in patterns such as in:
</p>
<sample><![CDATA[
transform [ 1 "c" 4 "duce" 2 6 ] with
   x & {{Sting}} -> [ x ]
]]></sample>
<p> The intended semantics of this expression was to extract the sequence of all
the strings occuring in the matched sequence. But because of the typo in
<code>St(r)ing</code> the transformation is instead the identity function:
<code>Sting</code> is considered as a fresh capture variable. CDuce however
detects that <code>Sting</code> is never used in the subsequent expression
and it pinpoints the possible presence of an error by issuing the
following warning:
</p>
<sessionsample><![CDATA[
Warning at chars 42-60:
{{%%   x & Sting -> [ x ]%%}}
The capture variable Sting is declared in the pattern but not used in 
the body of this branch. It might be a misspelled or undeclared type 
or name (if it isn't, use _ instead).
%%transform [ 1 "c" 4 "duce" 2 6 ] with
   x & Sting -> [ x ]%%
- : [ 1 [ 'c' ] 4 [ 'duce' ] 2 6 ] =
    [ 1 "c" 4 "duce" 2 6 ]
92

93
94
95
Ok.
]]></sessionsample>
</section>
96
97
98
99

</box>


100
<box title="Empty types" link="emptyty">
101
<p>
102
CDuce's type system can find very nasty errors. For instance look at this DTD declaration
103
</p>
104
105
106
107
108
<xmlsample><![CDATA[
<!ELEMENT person (name,children)>
<!ELEMENT children (person+)>
<!ELEMENT name (#PCDATA)>
]]></xmlsample>
109
<p>
110
111
Apparently this declaration does not pose any problem. But if you consider it more carefully you will see that there exists no document that can be valid for such a DTD,
as a person contains a sequence of children that contain a non empty
112
113
114
115
sequence of persons, etc generating an infinite tree.
</p>

<p>
116
Let us write the same type in CDuce and look at the result returned by the type-checker
117
</p>
118
119
120
121
122
123
124
125
126
127
128
129
<sessionsample><![CDATA[
type Person = <person>[ Name Children ]
type Children = <children>[Person+]
type Name = <name>[PCDATA]

Warning at chars 57-76:
%%type Children = %%{{%%<children>[Person+]%%}}
This definition yields an empty type for Children
Warning at chars 14-39:
%%type Person = %%{{%%<person>[ Name Children ]%%}}
This definition yields an empty type for Person
]]></sessionsample>
130
131
132
<p>
The type checker correctly issues a "Warning" to signal that the first 
two types  are empty. Note that instead the declarations</p>
133
134
<sample><![CDATA[
type Person = <person>[ Name Children ]
135
type Children = <children>[({{ref Person}})+]
136
137
type Name = <name>[PCDATA]
]]></sample>  
138
139
140
141
142
143
<p>
correctly do not yield any warning: in this case it is possible to build a value of type person (and thus of type children), for instance by using a recursive definition where a person is a child of itself.
</p>
<p>
We paid special care in localizing errors and suggesting solutions. 
You can  try it by
144
yourself by picking the examples available on the <a
145
href="http://reglisse.ens.fr/cgi-bin/cduce">on line interpreter</a> and putting in
146
147
148
149
them random errors.
</p>
</box>

150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
<box title="Unused branches" link="pr">
<p>
The emptiness test is used also to check for possible errors in the definition
of patterns. If the type checker statically determines that a pattern in a match
operation can never be matched then it is very likely that even if the match
expression is well-typed, the programmer had made an error.  This is determined by checking whether the intersection of set of all values that can be fed to the branch and the set of all values that  Consider for example
the following code:
</p>
<sample><![CDATA[
type Person = <person>[<name>String <tel>String  (<email>String)?]

fun main_contacts(x : [Person*]):[String*] =
  transform x with 
     | <_>[_ _ <{{emal}}>s] -> [s]
     | <_>[_  <tel>s ] -> [s]
]]></sample>  
<p>
167
This function was supposed to extract the list of contacts from a list of persons
168
169
170
171
elements giving priority to email addresses over telephone numbers.  Even if
there is a typo in the pattern of the first branch, the function is well
typed. However because of the typo the first branch will never be selected and
emails never printed. The CDuce type-checker however recognizes that this branch
172
173
has no chance to be selected since <code> Person &amp; &lt;_>[_ _
&lt;emal>s]</code>=<code>Empty</code> and it warns the programmer by issuing the following warning message:
174
</p>
175
176
177
178
179
180
181
182
183
184
<sessionsample><![CDATA[
Warning at chars 144-167:
%%       | %%{{%%<_>[_ _ <emal>;s] -> [s]%%}}
This branch is not used
%%fun main_contacts(x : [Person*]):[String*] =
    transform x with
       | <_>[_ _ <emal>s] -> [s]
       | <_>[_  <tel>s ] -> [s]%%
- : [ Person* ] -> [ String* ] = <fun>

185
Ok.
186
]]></sessionsample>
187
188
</box>

189
</page>